POJ 2063 Investment

来源:互联网 发布:便携式数据采集系统 编辑:程序博客网 时间:2024/06/06 06:45

完全背包问题。


我的背包训练第二题。按照背包九讲的步骤来搞。


题意是说给你一些本钱,然后有一些债券可以购买,不同的债券会有不同的利润,在规定年限内,利润要最大。


债券是无限制购买的,(完全背包)获得的利润可以买债券,(背包变大)

每年都可以选择债券,也就是每年都要重新开始,(每年一次)

最后得出你手上的钱有多少。这道题题目中提示了 1000的倍数。但是本钱不一定,利润也不一定。

只有债券在输入时候可以除1000。每年开始的时候,本钱除1000,不过也要保存 %1000。


02(笑)背包的自我修养:


F[0…V ] ← 0
for i   ←    1 to N
    for v   ←    Ci to M
        F[v]   ←    max(F[v]; F[v - Ci] +Wi)


伪代码,跟01背包有点相似,也有点不同。


C[]表示费用,W[]表示价值。M表示背包容量


01背包的第二个过程是反过来的,从M → 0;为了保证在考虑“选入第i 件物品”这件


策略时,依据的是一个绝无已经选入第i 件物品的子结果F[i - 1; M - Ci]。


完全背包却可能某种物品选择多次。


int dp[1000001];
int c[100001],v[100001];


memset(dp,0,sizeof(dp));


for(int i=0;i<n;i++)
        {
            for(int j=c[i];j<=m;j++)
                dp[j]=max(dp[j],dp[j-c[i]]+v[i]);
        }


已经坑到第二步,完全背包了。不过还得细细体会。

本题代码:


#include<cstdio>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<queue>#include<map>#include<stack>#include<iostream>#include<list>#include<set>#include<cmath>#define INF 0x7fffffff#define eps 1e-6using namespace std;int dp[100001];int c[11],v[11];int main(){    int t,m,n,year;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&year);        scanf("%d",&m);        for(int i=0; i<m; i++)        {            scanf("%d%d",&c[i],&v[i]);            c[i]/=1000;        }        memset(dp,0,sizeof(dp));        while(year--)        {            int tmp=n%1000;            n/=1000;            for(int i=0; i<m; i++)            {                if(c[i]>n)continue;                for(int j=c[i];j<=n;j++)                {                    dp[j]=max(dp[j],dp[j-c[i]]+v[i]);                }            }            int ans=0;            for(int i=0; i<=n; i++)                ans=max(ans,dp[i]);            n=n*1000+tmp+ans;        }        printf("%d\n",n);    }}




0 1