POJ 2063 Investment (完全背包)

哈哈这道题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 15
int 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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值