zoukankan      html  css  js  c++  java
  • 解题报告 solve

    3.solve(solve.pas/c/cpp)

    描述

    dsqwwe每个月都有m(0<=m<=1000)元的零花钱,他现在有n(n<=300)项消费计划,每个消费计划消耗2种费用,一种是要花掉当前月的零花钱,另一种是要花掉下一个月的零花钱,每个月的零花钱不能超支,若一个月的零花钱不能用完,dsqwwe会把钱花在其他地方,也就是说,每个月剩余的零花钱不会留给下一个月。问dsqwwe想要完成他所有的消费计划最少需要几个月。

    计划要顺序完成。

    输入(solve.in)

      第一行:m,n

      接下来的n行,每行两个整数a,b,描述一种消费计划,a代表花掉当前月的钱的数目,b代表花掉下个月的钱的数目(a,b<=m)

    输出(solve.out)

      需要最少的月数

    样例输入:

    100 5

    40 20

    60 20

    30 50

    30 50

    40 40

    样例输出:

    5

    样例解释:

    +------+-------+--------+---------+---------+--------+
    |      |零花钱 |解决问题| 当前支付| 下月预支|月底结余|
    |月份  |       |        |         |         |        |
    +------+-------+--------+---------+---------+--------+
    | 1    | 100   | 1, 2   | 40+60   | 0       | 0      |
    | 2    | 100   | 3, 4   | 30+30   | 20+20   | 0      |
    | 3    | 100   | -none- | 0       | 50+50   | 0      |
    | 4    | 100   | 5      | 40      | 0       | 60     |
    | 5    | 100   | -none- | 0       | 40      | 60     | 
    +------+-------+--------+---------+---------+--------+

    DP 

    首先,开 f[i,j] 表示前 个月做 个任务,最后一个月所能最多剩下的钱。

    然后,分析,枚举最后一个月做了最后 个任务,然后判断,也就是,这 个任务可以压缩到 个月来完成而不会预支,也就是总钱数在 以下,然后,取最大值转移。

    维的 DP 

     

    program liukeke;

    var

      a,b:array[0..301] of longint;

      f:array[0..601,0..301] of longint;

      x1,x2,n,m,i,j,k,ans:longint;

     

    function max(a,b:longint):longint;

    begin

     if a>b then exit(a);

     exit(b);

    end;

     

    begin

      assign(input,'solve.in');reset(input);

      assign(output,'solve.out');rewrite(output);

      readln(m,n);

      for i:=1 to n do

      begin

        readln(x1,x2);

    a[i]:=a[i-1]+x1;

    b[i]:=b[i-1]+x2;    // a,b 为 累和。

      end;

      fillchar(f,sizeof(f),128);  

      f[0,0]:=m;

      while true do

      begin

        inc(ans);

    for j:=1 to n do

      for k:=0 to j do

        if (f[ans-1,k]>=a[j]-a[k])and(m>=(b[j]-b[k])) then

    begin

                     f[ans,j]:=max(f[ans,j],m-(b[j]-b[k]));

      if f[ans,j]=m then break;   //不能更大值了

    end;

    if f[ans,n]>=0 then break;  //做完了

      end;

      writeln(ans+1);  //最后一拨任务影响的是两个月。

      close(input);

      close(output);

    end.

     

  • 相关阅读:
    tyvj 1031 热浪 最短路
    【bzoj2005】 [Noi2010]能量采集 数学结论(gcd)
    hdu 1394 Minimum Inversion Number 逆序数/树状数组
    HDU 1698 just a hook 线段树,区间定值,求和
    ZeptoLab Code Rush 2015 C. Om Nom and Candies 暴力
    ZeptoLab Code Rush 2015 B. Om Nom and Dark Park DFS
    ZeptoLab Code Rush 2015 A. King of Thieves 暴力
    hdoj 5199 Gunner map
    hdoj 5198 Strange Class 水题
    vijos 1659 河蟹王国 线段树区间加、区间查询最大值
  • 原文地址:https://www.cnblogs.com/SueMiller/p/2237119.html
Copyright © 2011-2022 走看看