POJ 3624 Charm Bracelet(TEST<29> 11.15)
解题思路
很明显的动态规划 0/1背包问题
但是 内存限制 需要 用 滚动数组 来进行dp
滚动数组优点:节约时间和 空间
缺点: 丢失中间的 状态(物品选择与否)
解决0/1背包问题 :就是对每一种物品 是否选择
怎样选择才能 达到在 在一定的 空间 内 达到 最优
每一种新空间最优解 的 产生 都依赖与之前 的最优解
下文 会给出 AC的滚动数组代码
以及 超内存的 二维 dp代码
AC 代码如下
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int val[3405],vol[3405];;
int dp[12890];
int main(){
int n,v;
cin>>n>>v;
for(int i=1;i<=n;i++)
cin>>vol[i]>>val[i];
for(int i=1;i<=n;i++){
for(int j=v;j>=vol[i];j--){
dp[j]=max(dp[j],dp[j-vol[i]]+val[i]);
//求解在特定空间中所能获得的最大 价值
// 可以找一组数据试试 比如
//5 6 1 3 2 5 2 6 1 9 2 6
//dp[]数据扫描的 是 每一个 物品在一定能放的 情况下
//如果出现新值大于 之前 最优 就更新为新的最优解
//更换过程中没有关注 是哪个物品 但是会显示出 价值的 高低
}
}
cout<<dp[v]<<endl;
return 0;
}
二维 dp 超内存 代码如下
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int val[3405],vol[3405];;
int dp[3405][12890];
int main(){
int n,v;
cin>>n>>v;
for(int i=1;i<=n;i++)
cin>>vol[i]>>val[i];
for(int i=1;i<=n;i++){
for(int j=0;j<=v;j++){
if(vol[i]>j)//空间不足
dp[i][j]=dp[i-1][j];//延续上一最优解
else//空间 取最优 策略(参考 滚动数组)
dp[i][j]=max(dp[i-1][j],dp[i-1][j-vol[i]]+val[i]);
}
}
cout<<dp[n][v]<<endl;
return 0;
}