zoukankan      html  css  js  c++  java
  • poj3265

    考状态的dp

    我的方法可能比较奇怪

    设f[i,j]表示第i个月解决j个问题可以最多解决到第几个问题

    容易知道,答案(月份)不会超过2n+1;

    f[i,j]=max(f[i-1,k]+j) 

    复杂度为O(n^3)

    代码如下

     1 var f:array[0..1000,0..500] of longint;
     2     b,a,sa,sb:array[0..500] of longint;
     3     p,y,q,i,j,k,n,m:longint;
     4 function max(a,b:longint):longint;
     5   begin
     6     if a>b then exit(a) else exit(b);
     7   end;
     8 
     9 begin
    10   readln(m,n);
    11   for i:=1 to n do
    12   begin
    13     readln(b[i],a[i]);
    14     sa[i]:=sa[i-1]+a[i];
    15     sb[i]:=sb[i-1]+b[i];
    16   end;
    17   f[1,0]:=0;
    18   i:=1;
    19   while i<=2*n+1 do
    20   begin
    21     inc(i);
    22     f[i,0]:=f[i-1,0];
    23     for j:=1 to n do
    24     begin
    25       if f[i-1,j]=0 then break;
    26       f[i,0]:=max(f[i,0],f[i-1,j]);
    27     end;
    28     for j:=1 to n do
    29     begin
    30       for k:=0 to n do
    31       begin
    32         if (f[i-1,k]=0) and (k<>0) then break;    //后面的状态不存在,直接退
    33         p:=f[i-1,k];
    34         q:=f[i-1,k]+j;
    35         if q>n then continue;
    36         y:=f[i-1,k]-k;
    37         if (sb[q]-sb[p]+sa[p]-sa[y]<=m) and (sa[q]-sa[p]<=m) then          //判断是否够这个月花的
    38           f[i,j]:=max(f[i,j],f[i-1,k]+j);
    39       end;
    40       if f[i,j]>=n then
    41       begin
    42         writeln(i+1);    //注意付完款一定是下个月
    43         halt;
    44       end;
    45       if f[i,j]=0 then break;
    46     end;
    47   end;
    48 end.
    View Code

    话说代码有的地方可能写的比较冗杂……

  • 相关阅读:
    【Linux基础】linux下修改ls显示的时间格式
    【Teradata】gtwglobal查看
    【Teradata】tdlocaledef修改默认日期配置
    【Linux基础】文件处理实例
    【Linux基础】awk命令
    【teradata】强制解锁
    第1节:保存文档
    Centos7安装MySQL数据库
    MyBatis框架之异常处理
    spring事务源码分析
  • 原文地址:https://www.cnblogs.com/phile/p/4473292.html
Copyright © 2011-2022 走看看