Diary 10.2.2014

嗯总算开始写今天的日记

今天似乎DP专场?

1. 采药(medic.pas/c/cpp)
【问题描述】
辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”
如果你是辰辰,你能完成这个任务吗?
【输入】
输入的第一行有两个整数n和m,用一个空格隔开。m代表总共能够用来采药的时间,n代表山洞里的草药的数目。接下来的n行每行包括两个整数,分别表示采摘某株草药的时间Ti和这株草药的价值Vi。
【输出】
输出包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。

刚开始看到的时候激动了下

【数据规模】
对于 50%的数据,n,m≤1000;
对于 100%的数据,n,m≤100000,Ti,Vi≤10。

= =!

然后看到了ti,vi

多重揹包

我加了点贪心优化

const shuru='medic.in';
		shuchu='medic.out';
var	hash:Array[0..11,0..11] of longint;
	w,v:array[0..100001] of longint;
	f:Array[0..100001] of longint;
	m,num,x,y,i,j,k,n,ans:longint;
procedure get(x,y,bei,mi:longint);
begin
	if bei=0 then exit;
	if bei>mi then begin
				    inc(num);
					w[num]:=x*mi; v[num]:=y*mi;
					get(x,y,bei-mi,mi*2);
				   end;
	if bei<=mi then begin
					 inc(num);
					 w[num]:=x*bei; v[num]:=y*bei;
					end;
end;
procedure init;
begin
	assign(input,shuru);
	assign(output,shuchu);
	reset(input);
	rewrite(output);
	readln(n,m);
	for i:=1 to n do
	begin
		readln(x,y);
		inc(hash[x,y]);
	end;
	for j:=10 downto 6 do
	while hash[1,j]>0 do
		begin
			if m>=hash[1,j] then begin
									m:=m-hash[1,j];
									inc(ans,j*hash[1,j]);
									hash[1,j]:=0;
								 end
							else begin
									hash[1,j]:=hash[1,j]-m;
									inc(ans,m*j);
									m:=0;
								 end;
			if m=0 then break;
		end;
	for i:=1 to 10 do
		for j:=1 to 10 do
			get(i,j,hash[i,j],1);
	close(input);
end;
function max(a,b:longint):longint;
begin
	if a>b then exit(a);
	exit(b);
end;
procedure main;
begin
	init;
	for i:=1 to num do
		for j:=m downto w[i] do
			f[j]:=max(f[j],f[j-w[i]]+v[i]);
	writeln(f[m]+ans);
	close(output);
end;
begin
	main;
end.
ps.标程写错害的我找了好久的错
2. 方格取数(matrix.pas/c/cpp)
【问题描述】
给定一个 n×m 的矩阵,记录左上角为(1,1),右下角为(n,m),现在从(1,1)开始取数,每次只
能向下或向右移动一个单位,最终到达(n,m),我们把路径上所有的数相乘,结果记为C。使C 的结
果最大已经不能满足我们了,现在我们想让C 末尾的零个数最少。
PS. 11000 末尾有三个零,100000100 末尾有两个零。
【输入】
第一行是两个正整数 n 和m,表示矩阵大小。
接下来 n 行每行m 个正整数,给出了整个矩阵。
【输出】
一个整数:最少的零的个数。

最开始想到了求2,5个数最小的。。然后认为错的就cha掉,,结果一直没想出来

其实就是找2个数最少的路和5个数最小的路

取他们之中最小的那个

没错我就是智商拙计的吴瑾昭

const shuru='matrix.in';
	  shuchu='matrix.out';
var f,g,a,b:Array[0..1001,0..1001] of longint;
	x,y,n,m,i,j,k:longint;
procedure init;
begin
	assign(input,shuru);
	assign(output,shuchu);
	reset(input);
	rewrite(output);
	readln(n,m);
	for i:=1 to n do
		for j:=1 to m do
			begin
				read(X);
				y:=x;
				while (y and 1=0) do
				begin
					inc(a[i,j]);
					y:=y shr 1;
				end;
				y:=x;
				while (y mod 5=0) do
				begin
					inc(b[i,j]);
					y:=y div 5;
				end;
			end;
	close(input);
	for i:=2 to n do
	begin
		f[0,i]:=1 shl 25;
		f[i,0]:=1 shl 25;
		g[i,0]:=1 shl 25;
		g[0,i]:=1 shl 25;
	end;
end;
function min(a,b:longint):longint;
begin
	if a<b then exit(A);
	exit(B);
end;
procedure main;
begin
	init;
	for i:=1 to n do
		for j:=1 to m do
		begin
			f[i,j]:=min(f[i-1,j],f[i,j-1])+a[i,j];
			g[i,j]:=min(g[i-1,j],g[i,j-1])+b[i,j];
		end;
	writeln(min(f[n,m],g[n,m]));
	close(output);
end;
begin
	main;
end.

3. 统计(count.pas/c/cpp)
【问题描述】
对于排列(P1,P2,P3,…Pn),定义(i,j)为逆序对当且仅当i<j 且Pi>Pj。统计{1,2,3,…,n}
的所有排列中,逆序对数量为m 的排列个数。

刚开始傻傻的以为是数学题。。就去找规律

然后发现是DP。。

设f[i,j]是1..i有j个逆序对的排列个数

f[i,j]=f[i-1,j-1]+f[i-1,j-2]+...f[i,j-(i-1)]

用前缀和优化一下O(n^2)

Code:

const shuru='count.in';
	  shuchu='count.out';
var	s,f:array[0..1001,-10..1001] of int64;
	m,i,j,k,n:longint;
procedure init;
begin
	assign(input,shuru);
	assign(output,shuchu);
	reset(input);
	rewrite(output);
	readln(n,m);
	close(input);
	for i:=1 to n do
	begin
		s[i,0]:=1;
		s[i,-1]:=0;
		f[i,0]:=1;
	end;
	s[1,1]:=1;
end;
Function max(a,b:longint):longint;
begin
	if a>b then exit(a);
	exit(b);
end;
Function min(a,b:longint):longint;
begin
	if a<b then exit(a);
	exit(B);
end;
procedure main;
begin
	init;
	for i:=2 to n do
	begin
		for j:=1 to min(m,i*(i-1) div 2) do
		begin
			f[i,j]:=(s[i-1,j]-s[i-1,max(-1,j-i)]) mod 1234567;
		end;
		for j:=1 to m do
			s[i,j]:=s[i,j-1]+f[i,j];
	end;
	writeln(f[n,m]);
	close(output);
end;
begin
	main;
end.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章