zoukankan      html  css  js  c++  java
  • Comet OJ

    ###题目链接###

    题目大意:一开始手上有 0 个节点,有 n 天抉择,m 种方案,在每天中可以选择任意种方案、任意次地花费 x 个节点(手上的节点数不能为负),使得在 n 天结束后,获得 y 个节点。

    其次,在每天结束后,会根据自己手上所具有的节点数来获得一些节点,设当天结束后所拥有 x 个节点,那么将获得 f(x) 个节点。

     

    分析:

    1、将全过程分为 n 天,每天开始有一定的节点数,然后 DP 求得花费后的最大价值(这个最大价值指的是,n 天结束后仅返还获得的最大节点数)。故设 dp[i][j] 表示在第 i 天花费操作完后,所能在最后一天返还节点数的最大值。

    2、很显然这是一个完全背包问题。在 DP 处理每天话费节点之前,需要更新当天最开始所拥有的节点数所代表的 价值 (即结束返还的总节点数)。而当天一开始的节点数由上一天末尾所持有的节点数 x  + 上一天结束后获得的节点数 f(x) 。

    故枚举上一天结束后所持有的节点数 j ,则有: dp[i][j+f[j]]=max( dp[i][j+f[j]] , dp[i-1][j] ) 。

     

    直接枚举物品数:

     

    #include<iostream>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    int n,m,k;
    int s[1008];
    int dp[108][2008];
    struct Good{
        int a,b;
    }A[108];
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<=k;i++) scanf("%d",&s[i]);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&A[i].a,&A[i].b);
        }
        memset(dp,0xc0c0c0c0,sizeof(dp));
        dp[1][0]=0;
        for(int i=2;i<=n;i++){
            for(int j=0;j<=k;j++){
                dp[i][j+s[j]]=max(dp[i][j+s[j]],dp[i-1][j]);
            }
            for(int w=1;w<=m;w++){
                for(int j=A[w].a;j<=2000;j++){
                    for(int e=1;e<=j/A[w].a;e++){
                        dp[i][j-e*A[w].a]=max(dp[i][j-e*A[w].a],dp[i][j]+e*A[w].b);
                    }
                }
            }
        }
        int ans=0;
        for(int i=0;i<=2000;i++){
            ans=max(ans,dp[n][i]+i+s[i]);
        }
        printf("%d
    ",ans);
    }

     

     

     优化要注意的是:由于这里的 dp 转移方程的方向是从末端向前转移过来的,而完全背包优化掉一个循环的原理是要用到在本层之前的物品状态,故枚举方向对应的也需要从末端向前端。

    #include<iostream>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    int n,m,k;
    int s[1008];
    int dp[108][2008];
    struct Good{
        int a,b;
    }A[108];
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<=k;i++) scanf("%d",&s[i]);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&A[i].a,&A[i].b);
        }
        memset(dp,0xc0c0c0c0,sizeof(dp));
        dp[1][0]=0;
        for(int i=2;i<=n;i++){
            for(int j=0;j<=k;j++){
                dp[i][j+s[j]]=max(dp[i][j+s[j]],dp[i-1][j]);
            }
            for(int w=1;w<=m;w++){
                for(int j=2000;j>=A[w].a;j--){
                    dp[i][j-A[w].a]=max(dp[i][j-A[w].a],dp[i][j]+A[w].b);
                }
            }
        }
        int ans=0;
        for(int i=0;i<=2000;i++){
            ans=max(ans,dp[n][i]+i+s[i]);
        }
        printf("%d
    ",ans);
    }

     

  • 相关阅读:
    ubutu安装phonegap 后出现/usr/bin/env:node No such file or directory的错误
    Ubuntu 14.04 x64 安装 Android SDK
    ubuntu64安装ia32-libs
    redis 配置
    flask部署阿里云
    爬虫数据存储
    selnuim 使用
    python 爬虫解析_1_
    scrapy 数据存储mysql
    scrapy 小案例
  • 原文地址:https://www.cnblogs.com/Absofuckinglutely/p/11878334.html
Copyright © 2011-2022 走看看