vijos-p1322 2008.11.8

来源:互联网 发布:android adb for mac 编辑:程序博客网 时间:2024/04/30 00:41

vijos-p1322 2008.11.8

描述 Description  

     过去的日子里,农夫John的牛没有任何题目. 可是现在他们有题目,有很多的题目

精确地说,他们有P (1 <= P <= 300) 道题目要做. 他们还离开了农场并且象普通人一样找到了工作. 他们的月薪是M (1 <= M <= 1000) 元.

他们的题目是一流的难题,所以他们得找帮手.帮手们不是免费的,但是他们能保证在一个月内作出任何题目.每做一道题需要两笔付款, 第一笔A_i(1<= A_i <= M)元在做题的那一个月初支付, 第二笔B_i元(1 <= B_i <= M)在做完后的下一个月初支付. 每一个月牛们用上一个月挣的钱来付款. 牛没有任何存款意识, 所以每个月的节余都回拿用去买糖吃掉了.

因为题目是相互关连的,它们必须按顺序解出. 比如,题目3必须在解题目4

之前或同一个月解出.

找出牛们做完所有题目并支付完所有款项的最短月数.

输入格式 Input Format

第一行: M 和 P;

第2...P+1行: 第i行包含A_i和B_i, 分别是做第i道题的欲先付款和完成付款.

输出格式 Output Format

   第一行: 牛们做完题目和付完帐目的最少月数.

样例输入 Sample Input

1005

4020

6020

3050

3050

4040

样例输出 Sample Output

6

分析:

 

这道题目是道DP题,由于做题是有序的,所以就有了阶段,我们用f[k,i]表示前k天完成前i道题的最小欠费,方程为f[k,i]:=min{sum_b[j+1,i]|sum_a[j+1,i]+f[k-1,j]<=m}sum_a[j,i]表示a[j]a[i]的和,sum_b亦然;结束条件是f[kp]=0f数组初始为oo

//今天见识到了dp的循环终值是不定的题目

program p1322;constfin     ='psolve.in';fou     ='psolve.out';maxn     =300+2;          oo                        =20000000;vara,b     :array[0..maxn]of longint;sum_a,sum_b    :array[0..maxn,0..maxn]of longint;f     :array[0..2*maxn,0..maxn]of longint;n,p,ans     :longint;procedure openfile;beginassign(input,fin);assign(output,fou);reset(input);rewrite(output);end;procedure closefile;beginclose(input);close(output);end;procedure init;vari     :longint;beginopenfile;readln(p,n);for i:=1 to n do begin    readln(a[i],b[i]);end;end;procedure get_sum;vari,j,_sum    :longint;begin_sum:=0;for i:=1 to n do begin    _sum:=_sum+a[i];    sum_a[1,i]:=_sum;    for j:=2 to i do begin     sum_a[j,i]:=sum_a[1,i]-sum_a[1,j-1];    end;end;_sum:=0;for i:=1 to n do begin    _sum:=_sum+b[i];    sum_b[1,i]:=_sum;    for j:=2 to i do begin     sum_b[j,i]:=sum_b[1,i]-sum_b[1,j-1];    end;end;end;procedure main;vark,i,j     :longint;beginget_sum;fillchar(f,sizeof(f),0);k:=1;f[1,0]:=0;for i:=1 to n do f[1,i]:=oo;repeat    inc(k);for i:=0 to n dobeginf[k,i]:=oo;     for j:=i downto 0 do begin//倒者循环更快!      if sum_a[j+1,i]+f[k-1,j]<=p then begin//上一个月的欠费+这个月初要付的钱<=m时       f[k,i]:=sum_b[j+1,i];//当前月的欠费就更新       break;      end;     end;    end;until f[k,n]=0;ans:=k;end;procedure print;beginwriteln(ans);closefile;end;begininit;main;print;end.


0 0
原创粉丝点击