POJ 2063 Investment (完全背包)

来源:互联网 发布:wifi网络优化加速软件 编辑:程序博客网 时间:2024/05/16 08:16

哈哈这道题T了好多次了,各种T!不过思路很明确,完全背包的求解,这道题最大的优化就是债券的价钱是1000的整数倍。我其实一开始就想到了用这个优化,但是题目中没有说明给的总的钱数也是1000的整数倍,所以交了几次都是直接T掉的。

后来想了下,其实可以对钱和债券的价格都除以1000,这个是没有问题的,因为我们看价格是1000的整数倍,而我们看如果总的钱数是xxx abc,尽管总的钱数不是1000的整数倍,但是我们在解决背包问题的时候,后面的零头abc是不可能影响我们选择债券的。因为后面的零头abc根本不可能足够买任何一个债券。所以我们可以对总的钱数也除以1000.然后进行完全背包的求解。

还有一个优化就是我们不需要每次都对dp进行初始化,因为我们所可以选择的债券的种类是不变的,只是总的钱数改变而已。因此我们可以在原有的基础上进行直接的优化就可以了,这只是背包在选择的过程中逐步找到更好解的过程。

下面贴上我的代码:

#include <stdlib.h>#include <stdio.h>//#include <iostream>#include <string.h>#define Max 2000000#define NUM 15int dp[Max];int c[NUM];int w[NUM];int main(){    int t,v,n,i,j,time;    double V;    int ans;    scanf("%d",&t);    while(t--)    {        scanf("%d %d",&v,&time);        scanf("%d",&n);        for(i=1;i<=n;i++)        {            scanf("%d %d",&c[i],&w[i]);            c[i]/=1000;        }                ans=v;        int up;        memset(dp,0,sizeof(dp));        for(int cas=0;cas<time;cas++)        {            V=(double)(ans)/1000.0;            for(i=1;i<=n;i++)            {                up=(int)(V);                for(j=c[i];j<=up;j++)                {                    int temp=dp[j-c[i]]+w[i];                    if(temp>dp[j])                        dp[j]=temp;                }            }            ans+=dp[up];        }        printf("%d\n",ans);    }    return 0;}


原创粉丝点击