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