这有一篇完全背包的详解,也加了判断是否恰好装满的状态传送门(Piggy-Bank)
题意在代码注释中有,算是完全背包的模板题吧,但是需要注意一点,因为题目中说了所有数据都是1000的倍数,所以我们可以对数据都进行缩小1000倍来进行计算。
AC代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#define MAX(a,b) a>b?a:b
using namespace std;
const int MAXN = 100000; // 数组不要开的太大,因为开的太大TLE了好多次
int dp[MAXN];
int val[15];
int w[15];
int T,n,m,y,sum;
int main()
{
scanf("%d",&T);
while(T--){
scanf("%d%d",&sum,&y);
scanf("%d",&m);
for(int i=0;i<m;i++){
scanf("%d%d",&val[i],&w[i]);
val[i] /= 1000; // 因为题上说了数据都能被1000除尽,所以在这里压缩一下
}
for(int i=0;i<y;i++){ // 因为有y年,所以需要循环y次
memset(dp,0,sizeof(dp)); // 每次循环都需要初始化dp,记录每一年的值
int s = sum/1000; // 将本金也压缩
for(int j=0;j<m;j++){ // 完全背包过程
for(int k=val[j];k<=s;k++){
dp[k] = MAX(dp[k],dp[k-val[j]]+w[j]);
}
}
sum += dp[s]; // 钱数+利息
}
printf("%d\n",sum);
}
return 0;
}
/***
[来源] POJ 2063
[题目] Investment
[题意]
银行存钱的问题,问怎样选择才能获得最大收益,先是输入本金,然后输入要存多少年,然后输入n行数据,一行
数据两个值,一个是投资价格,一个是收益而已把本金当作背包容量,然后就是一个完全背包问题,唯一不同的是
需要循环y年。
[输入]
1
10000 4
2
4000 400
3000 250
[输出]
14050
*/