POJ 2184 01 背包问题

    这几天主要学习动态规划,首先从01背包问题开始。

    从这道题目来看,我之前对01背包理解的还不够深刻,比如说第二层循环中,是逆序还是正序查找,对此我就没有搞清楚。所以在这里反思一下,同时也总结一下这道题。

     1。对于最基础的背的体积V 和收益C,我以前总是以为V是作为限制条件出现的,但通过这道题我有所改观,我们可以把V作为转换成本题的SI,C转换成本题的FI,这样,V 就不在是一个限制条件,而是作为表明此时SI的状态,和此在这里面存的数的性质是一样的。

     2。就是第二次循环的是逆向还是正向的问题,其实这个问题的本质就是,如种循序能够不重复取,这是01背包区别于完全背包的标志所在。

#include<iostream>
#include<cstdio>
#define min -99999999
using namespace std;
struct cows{
    int si,fi;
};
cows s[110];
int dp[200010];
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        for(int i=1;i<=n;i++)
            scanf("%d %d",&s[i].si,&s[i].fi);

        for(int i=0;i<=200000;i++)dp[i]=min;
        dp[100000]=0;
        for(int i=1;i<=n;i++){//cout<<i<<endl;
            if(s[i].si>0){
                for(int j=200000;j>=s[i].si;j--)
                    if(dp[j-s[i].si]!=min){
                        dp[j]=max(dp[j],dp[j-s[i].si]+s[i].fi);
                       // cout<<j<<" "<<dp[j]<<endl;
                        }
                        }
            else{
                for(int j=0;j<=200000+s[i].si;j++)
                 if(dp[j-s[i].si]!=min){
                        dp[j]=max(dp[j],dp[j-s[i].si]+s[i].fi);
                        //cout<<j<<" "<<dp[j]<<endl;
                        }

                        }
        }

        int max1=min;
        for(int i=100000;i<=200000;i++){
               // cout<<dp[i]<<" ";
            if(dp[i]>0&&max1<dp[i]+i-100000)
            max1=dp[i]+i-100000;}
       if(max1!=min) printf("%d\n",max1);
       else  printf("0\n");

    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值