洛谷P2392 kkksc03考前临时抱佛脚

P党的福利

这道题可以用dp的方法来做。其实和01背包差不多。

其实就是将每个科目的所有复习时间分成两部分,尽量使得两部分的总时间都接近一半。

背包结束后f[m/2]总是小于等于m-f[m/2],要加最大值。这就是这道题的唯一坑点吧……

没学过01背包请先看看 P2871 ,链接放这不谢。一定要学会哦~

下面上代码:

var
w:array[1..100000] of longint;
f:array[1..100000] of longint;
a,b,c,d,ans,i:longint;
function max(a,b:longint):longint;
begin
if a>b then exit(a)
else exit(b);
end;
procedure dp(n:longint);//dp函数,要用就拿来用
var
i,j,cnt:longint;
begin
fillchar(f,sizeof(f),0);
cnt:=0;
for i:=1 to n do inc(cnt,w[i]);
for i:=1 to n do
for j:=cnt div 2 downto w[i] do
f[j]:=max(f[j],f[j-w[i]]+w[i]);//状态转移方程
inc(ans,cnt-f[cnt div 2])//(坑点)
end;
begin
readln(a,b,c,d);
ans:=0;
for i:=1 to a do read(w[i]); readln; dp(a);
for i:=1 to b do read(w[i]); readln; dp(b);
for i:=1 to c do read(w[i]); readln; dp(c);
for i:=1 to d do read(w[i]); readln; dp(d);
writeln(ans);
end.

猜你喜欢

转载自www.cnblogs.com/iycc/p/9069202.html