题目:
过去的日子里,农夫John的牛没有任何题目. 可是现在他们有题目,有很多的题目.精确地说,他们有P (1 <= P <= 300) 道题目要做. 他们还离开了农场并且象普通人一样找到了工作. 他们的月薪是M (1 <= M <= 1000) 元.
他们的题目是一流的难题,所以他们得找帮手.帮手们不是免费的,但是他们能保证在一个月内作出任何题目.每做一道题需要两比付款, 第一笔A_i(1 <= A_i <= M)元在做题的那一个月初支付, 第二笔B_i元(1 <= B_i <= M)在做完后的下一个月初支付. 每一个月牛们用上一个月挣的钱来付款. 牛没有任何存款意识, 所以每个月的节余都回拿用去买糖吃掉了.
因为题目是相互关连的,它们必须按大概顺序解出. 比如,题目3必须在解题目4之前或同一个月解出. 找出牛们做完所有题目并支付完所有款项的最短月数.
Input
100 5 40 20 60 20 30 50 30 50 40 40output
6
分析:贪心gg,不过不知道为啥40分有人30分。正解dp 设f[i,j]表示最后一个月做i~j题花费的月数那就有两种情况:1、f[i,j]=min(f[k,i-1]+1)(隔一个月做)2、f[i,j]=min(f[k,i-1]+2)(隔两个月做)ans:=min(ans,f[i,p]);
代码:
const
maxn=500;
var
f:array [0..maxn,0..maxn*2] of longint;
a:array [0..maxn,1..2] of longint;
ans,n,m:longint;
function min(x,y:longint):longint;
begin
if x>y then
exit(y);
exit(x);
end;
procedure init;
var i:longint;
begin
readln(n,m);
for i:=1 to m do
readln(a[i,1],a[i,2]);
end;
procedure main;
var
i,j,k,sum:longint;
begin
fillchar(f,sizeof(f),$7f);
f[0,n]:=2;
for i:=0 to m do
begin
for j:=0 to n do
begin
if f[i,j]=maxlongint then
continue;
sum:=n;
ans:=j;
for k:=i+1 to m do
begin
dec(ans,a[k,1]);
if ans<0 then
break;
dec(sum,a[k,2]);
if sum<0 then
break;
f[k,sum]:=min(f[k,sum],f[i,j]+1);
end;
f[i,n]:=min(f[i,n],f[i,j]+1);
end;
end;
ans:=maxlongint;
for i:=0 to n do
ans:=min(ans,f[m,i]);
writeln(ans);
end;
begin
init;
main;
end.