POJ 3624 Charm Bracelet(0/1背包)(TEST 11.15)

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;
}
发布了55 篇原创文章 · 获赞 1 · 访问量 975

猜你喜欢

转载自blog.csdn.net/weixin_43556527/article/details/103102071
今日推荐