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.


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