0-1背包

01背包虽然比较简单,但理解感觉还是挺费劲的(我觉得),所以呢,我从最基础的题开始,希望能慢慢进步奋斗,举个栗子大笑


经过抽签选择,小智将军第一个进入考场。

菜虫:(身上散射出华贵(?)的光芒)欢迎你,第一位挑战者!!
小智:……(走到菜虫身后,关灯)女王陛下,虽然我们国家现在很富裕,但也请您不要浪费电来用这么大功率的灯泡。

菜虫(汗):啊啊~~爱卿所言甚是~~那么,你的题目是……我们的情报组织探听到敌人的重要将领——小飞侠星期天会邀他的灵儿妹妹到公园去玩。公园里有很多娱乐项目,可并不是每一项他们都喜欢,所以他们对每一项都进行了“喜欢度”的评分。因为小飞侠也是一个了不起的角色,所以他一定会选择在有限时间内的最好的方案。现在要你做的就是找出在规定时间内他们选择哪几项不同的活动可以使其“喜欢度”之和达到最大,据此我们就可以知道他会在哪些地方出现,从而在那里派人看守了。

小智:(灯泡一亮)每个地方都派人看守不就行了?!
“当~~~”
菜虫:(手执八公分直径炒锅,筋)……你是白痴吗?-_-##(都派人去看守的话我们会有多少桌三缺一?!)听好了,输入格式是第一行一个正整数N(1<=N<=100)表示总共的娱乐项目数;第二行一个正整数表示规定的时间t(0<t<1000);下面有N行,其中第i+2行有两个正整数fi(0<=fi<=100)和ti(0<ti<=100),分别表示对项目i的“喜欢度”和它所耗费的时间。输出的时候在第一行输出最大的“喜欢度”之和,下面给你一个样例:

样例1

样例输入1

3
5
1 2
5 5
4 3

样例输出1

5

限制

各个测试点1s
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,t;
    int dp[105][1005];
    memset(dp,0,sizeof dp);
    int v,w;
    cin>>n;
    cin>>t;
    for(int i=1;i<=n;i++)   /*表示从前i个项目开始选取*/
    {
        cin>>v>>w;      /*可不用存储喜欢度和时间*/
        for(int j=0;j<=t;j++)
        {
          dp[i][j]=(i==1?0:dp[i-1][j]);    /*很重要,j<w时也要转移状态*/
            if(j>=w)
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-w]+v);
        }
    }
    cout<<dp[n][t]<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/shaohang_/article/details/80753783