[题目来源]:VIjos
[关键字]:动态规划
[题目大意]:用n块水晶搭建两个塔,要求双塔必须一样高,问最大能达到的高度为多少。
//============================================================================================================
[分析]:用f[i,j]表示使用前i个水晶,建起高度差为j的双塔时,较矮的那个塔的最大高度是多少。这样的话,对于每一块水晶都有三种决策,不使用,放到高塔上,放到矮塔上.而放到矮塔上会有两种情况,一是使矮塔的高度超过了高塔,二是没有超过。具体如下:
if f[1-t,j]>f[t,j] then f[t,j]:=f[1-t,j];//不使用if f[1-t,j]>f[t,j+h[i]] then f[t,j+h[i]]:=f[1-t,j];//高塔if j>=h[i]//判断会不会使矮塔变成高塔 then begin if f[1-t,j]+h[i]>f[t,j-h[i]] then f[t,j-h[i]]:=f[1-t,j]+h[i]; end//不会 else begin if f[1-t,j]+j>f[t,h[i]-j] then f[t,h[i]-j]:=f[1-t,j]+j; end;//会 这样DP就可以了。边界是f[0,0]:=0;目标是f[n,0];//出自tyvj1114题解//==========================================================================================================
[代码]:
View Code
1 program Project1; 2 var 3 n: longint; 4 a, s: array[0..200] of longint; 5 f: array[0..200,0..2500] of longint; 6 7 procedure init; 8 var 9 i: longint; 10 begin 11 readln(n); 12 for i := 1 to n do read(a[i]); 13 for i := 1 to n do s[i] := s[i-1]+a[i]; 14 end; 15 16 procedure work; 17 var 18 i, j: longint; 19 begin 20 fillchar(f,sizeof(f),200); 21 f[0,0] := 0; 22 for i := 1 to n do 23 for j := 0 to s[i] do 24 begin 25 if f[i-1,j] > f[i,j] then f[i,j] := f[i-1,j]; 26 if f[i-1,j] > f[i,j+a[i]] then f[i,j+a[i]] := f[i-1,j]; 27 if j >= a[i] then 28 if f[i-1,j]+a[i] > f[i,j-a[i]] then f[i,j-a[i]] := f[i-1,j]+a[i]; 29 if j < a[i] then 30 if f[i-1,j]+j > f[i,a[i]-j] then f[i,a[i]-j] := f[i-1,j]+j; 31 end; 32 if f[n,0] > 0 then writeln(f[n,0]) else writeln('Impossible'); 33 end; 34 35 begin 36 assign(input,'c:\1.in');reset(input); 37 assign(output,'c:\1.out');rewrite(output); 38 init; 39 work; 40 close(input); 41 close(output); 42 end.