码迷,mamicode.com
首页 > 其他好文 > 详细

Comet OJ - Contest #11 B- usiness

时间:2019-09-24 21:00:49      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:color   iostream   ems   for   ble   memset   com   max   mes   

原题链接

题意:

有 n 天, m 种投资方案,以及余额小于等于 k 时的补贴 f[x] 。

每一天可以选择投资方案进行无限次数投资(但要保证余额大于等于0),在n天结束之后投资的回报才会返回。

求最大的投资回报为多少。

思路:

这种投资花钱,然后最后收获可以转化为完全背包问题。同时由于每一天的余额状态多样,所以在每一天开始也要对状态进行转移。

设dp[i][j]为 第i天,余额为j。那么每天开始状态转移为 : dp[ i ][ j + f [ j ] ] = max ( dp[ i ][ j + f [ j ] ],dp [ i-1 ][ j ] ); // f[ j ] 为补贴函数

然后对当天进行完全背包的转移

code: (其他看代码注释)

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int inf = 0x3f3f3f3f; 
int f[2050];//(0<=k<=1000),(k+f[k]<=2000)
int v[110],w[110];//(1<=m<=100)
int dp[105][3005];//max(i+f[i])
int main(){
    int n,m,k;
    cin>>n>>m>>k;
    //某天手上剩余钱最大值 
    int mmax = 0; 
    for(int i=0;i<=k;i++){
        scanf("%d",&f[i]);
        mmax = max(mmax,f[i]+i);
    }
    for(int i=1;i<=m;i++){
        scanf("%d%d",&v[i],&w[i]);
    }
    memset(dp,-inf,sizeof(dp));
    dp[1][0]=0;
    for(int l=2;l<=n;l++){
        for(int j=0;j<=k;j++)
            dp[l][j+f[j]]=max(dp[l][j+f[j]],dp[l-1][j]);
        for(int i=1;i<=m;i++){
            for(int j=mmax-v[i];j>=0;j--){
                dp[l][j]=max(dp[l][j],dp[l][j+v[i]]+w[i]);
            }
        }
    }
    //最后一天状态更新 
    int ans=0;
    for(int i=0;i<=mmax;i++){
        ans=max(ans,dp[n][i]+i+f[i]);
    }
    cout<<ans<<endl;
}

 

Comet OJ - Contest #11 B- usiness

标签:color   iostream   ems   for   ble   memset   com   max   mes   

原文地址:https://www.cnblogs.com/Tianwell/p/11580934.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!