20 条题解

  • 1
    @ 2020-05-24 12:18:43

    我终于过了QAQ

    #include <cstdio>
    #include <cstring>
    #define N 21
    int na,nb,n,ta[N],tb[N],ka[N],kb[N],tim[N][61][61],dp[N][61][61];
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    inline int max(int x,int y){return x>y?x:y;}
    inline int min(int x,int y){return x<y?x:y;}
    inline void calc(int x){
        int t[2][61][61];//0--A,1--B
        memset(t,0x3f,sizeof(t));
        t[1][0][0]=t[0][0][0]=0;
        for(int i=0;i<=na;++i)
            for(int j=0;j<=nb;++j){
                for(int k=1;k<=i;++k) t[0][i][j]=min(t[0][i][j],t[1][i-k][j]+ta[x]+ka[x]*k*k);
                for(int k=1;k<=j;++k) t[1][i][j]=min(t[1][i][j],t[0][i][j-k]+tb[x]+kb[x]*k*k);
                tim[x][i][j]=min(t[0][i][j],t[1][i][j]);
            }
    }
    int main(){
    //  freopen("a.in","r",stdin);
        na=read();nb=read();n=read();
        for(int i=1;i<=n;++i) ta[i]=read(),tb[i]=read(),ka[i]=read(),kb[i]=read();
        for(int i=1;i<=n;++i) calc(i);
        memset(dp,0x3f,sizeof(dp));
        for(int i=0;i<=na;++i)
            for(int j=0;j<=nb;++j)
                dp[1][i][j]=tim[1][i][j];
        for(int x=2;x<=n;++x)
            for(int i=0;i<=na;++i)
                for(int j=0;j<=nb;++j){
                    for(int ki=0;ki<=i;++ki)
                        for(int kj=0;kj<=j;++kj)
                            dp[x][i][j]=min(dp[x][i][j],max(dp[x-1][i-ki][j-kj],tim[x][ki][kj]));
                }
        printf("%d\n",dp[n][na][nb]);
        return 0;
    }
    
    
  • 0
    @ 2009-10-07 17:26:43

    解法一

    首先很容易想到DP两次

    第1次 f1(k,i,j)表示 第K台机器,处理i个a任务,j个b任务的最小时间

    第2次 背包(p*na^2*nb^2) 没有puppy的大力支持会超2个点

    当然+上oimaster大牛的优化后可以解决这个问题

    PS:这个优化我一直写不好(囧)

    ___|\__|\__|\__|\__|\__|\__|\__|_内有恶狗,切勿靠近___|\__|\__|\__|\__|\__|\__|\__|__

    解法二

    DP+2分答案(用1维背包判断可行性)

    问题完美解决

  • 0
    @ 2009-09-03 21:21:56

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:0ms

    var i,j,n,m,p,k,q,x,y,mm,an:longint;

    a,b:array[1..200,1..4]of longint;

    g:array[0..20,0..200,0..200,1..2]of longint;

    f:array[0..100]of longint;

    d:array[1..20,0..100]of longint;

    function min(o,s:longint):longint;

    begin

    if os then exit(o)else exit(s);

    end;

    procedure zhao(l,r:longint);

    begin

    if l=r then begin an:=l;exit;end;

    for i:=1 to m do

    f[i]:=-999;

    f[0]:=0;

    for i:=1 to p do

    for j:=0 to m do

    d:=-999;

    x:=(l+r)div 2;

    for i:=1 to p do

    for j:=0 to m do

    for k:=0 to n do

    if g=0 then

    f[j]:=max(f[j-k]+d,f[j]);

    if f[m]>=n then begin zhao(l,x);exit;end

    else begin zhao(x+1,r);exit;end;

    end;

    begin

    read(m,n,p);

    for i:=1 to p do

    for j:=1 to 4 do

    read(a);

    fillchar(g,sizeof(g),$7F);

    for i:=1 to p do

    begin

    g:=0;g:=0;

    end;

    for i:=1 to p do

    for j:=0 to m do

    for k:=0 to n do

    begin

    for q:=0 to j-1 do

    g:=min(g+a*(j-q)*(j-q)+a,g);

    for q:=0 to k-1 do

    g:=min(g+a*(k-q)*(k-q)+a,g);

    end;

    for i:=1 to p do

    for j:=0 to m do

    for k:=0 to n do

    g:=min(g,g);

    mm:=99999999;

    for i:=1 to p do if mm>g then mm:=g;

    zhao(1,mm);

    writeln(an);

    end.

    用二分查找法解题

    终于过了 AC率啊

  • 0
    @ 2009-06-18 21:35:01

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 56ms

    ├ 测试数据 06:答案正确... 41ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:97ms

    黑书上写得很深奥,我没看懂。觉得oimaster神牛的方法很简单有效。膜拜神牛!

  • 0
    @ 2009-05-19 21:04:25

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 25ms

    ├ 测试数据 06:答案正确... 9ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:34ms

    剪枝剪错。。。50->70->100。。。膜拜oimaster!!!

  • 0
    @ 2009-05-14 18:36:49

    此题可以有

    枚举当前点做多少工作

    可以加个优化

    如果枚举之前点做多少工作

    那个优化的作用就体现不出了

  • 0
    @ 2009-04-24 07:48:14

    饿

  • 0
    @ 2009-04-21 22:15:52

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:0ms

    puppy 就是 神奇 ……

    明明 最坏 大概 会运算 2*10^8还多 , 结果 竟然……

    DP + 弱弱 的 类似 最优化 剪枝 ……

    引用 黑书 上的: 先 枚举 决策 再 枚举 状态,容易 进行“剪枝”。

    不过 那 上面 介绍的上下界 估计 看不懂 的说…… 于是 自己 随便找个,结果 貌似还不错 囧……

  • 0
    @ 2009-04-19 21:08:13

    Accepted 有效得分:100 有效耗时:0ms

    我个人认为楼下的楼下大牛说得很对,二分的确很快。

    首先预处理是求出第i个计算机做x1个a类任务和x2个b类任务,方程很好写。

    之后二分最差运行时间,每次计算前i台计算机在不超过上限时间的情况下

    做x1个a类任务的同时能最多做多少个b类任务,剩下的就是输出了

  • 0
    @ 2009-04-19 20:17:17

    做两次DP。

    第一次求第i个计算机做x1个a类任务,x2个b类任务所需的组少时间g。

    第二次求前i个计算机做x1个a类任务,x2个b类任务所需的组少时间f。

    第二次DP的时间复杂度为O(p*na^2*nb^2),实测会超时,只要加一个小优化。

    因为第二次DP是取最大值,并且很容易得到:

    当x1'>=x1,x2'>=x2时,g>=g。

    所以说如果第i个计算机处理的时间超过了前面i-1个计算机处理的时间,再让第i个计算机做更多的工作只会增加时间,可以剪枝。

    这样的话:

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 41ms

    ├ 测试数据 06:答案正确... 56ms

  • 0
    @ 2009-04-17 08:03:06

    暴力DP

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 103ms

    ├ 测试数据 05:答案正确... 509ms

    ├ 测试数据 06:答案正确... 666ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:1278ms

  • 0
    @ 2009-04-16 19:08:47

    Accepted 有效得分:100 有效耗时:231ms

    暴力DP,加个小剪枝就AC了

  • 0
    @ 2009-04-17 22:09:11

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:0ms

    想到了个新方法,貌似不错.

    大家貌似是双重dp

    我是用dp预处理然后二分答案

  • 0
    @ 2009-04-16 14:02:36

    Accepted 有效得分:100 有效耗时:1263ms

    庆祝AC 250 题!

    DP,但一定要加剪枝!

  • 0
    @ 2009-04-15 22:55:18

    卡时,加剪枝,加RP,加puppy

  • 0
    @ 2009-04-15 21:16:05

    线形双重DP。。。

  • 0
    @ 2009-04-15 20:44:51

  • 0
    @ 2009-04-15 20:24:10

    动态规划

    参见黑书.

  • -1
    @ 2013-03-25 23:10:48

    试问大牛们如何A的那么完美,吾的code除了tle就是re,求解释

  • -1
    @ 2009-09-27 20:04:25

    二分的确快!!!!

  • 1

信息

ID
1534
难度
6
分类
动态规划 | 背包动态规划 点击显示
标签
递交数
345
已通过
94
通过率
27%
被复制
2
上传者