背包背包
http://www.codevs.cn/problem/3111/
CYD啃骨头
题目描述 Description
CYD吃饭时有N个骨头可以啃,但CYD要午睡了,所以他只有M分钟吃饭,已知啃每个骨头需花费时间Ai,可以得到Bi个单位的营养。问CYD最多得到多少营养。
输入描述 Input Description
M N
A1 B1
A2 B2
……
AN BN
输出描述 Output Description
得到的最大营养值
样例输入 Sample Input
10 3
5 20
3 15
8 29
样例输出 Sample Output
35
数据范围及提示 Data Size & Hint
对于100%的数据 N≤100 M≤1000 Ai,Bi≤100
这是我的第一道背包题,没想到是以这样的题目表述,感觉无力吐槽。
最简单的背包就是这种类型(01背包)。一个V的容器,N个物品,每个物品都有一定的体积v和价值w。要求往容器里装w总和最大的若干个物品。那么我们在对于一个物品是否装入的判断标准就是在已有的情况下装下它,w总和是否增加,如果装不下了,就要舍弃之前装进来的某些物品
#include <iostream>
#include<algorithm>
using namespace std;
int main()
{ int N,M;
cin>>N>>M;
int t[1000+10]={0},v[1000+10]={0};
for(int i=1;i<=M;i++)
{
cin>>t[i]>>v[i];//记录
}
int F[1000+10]={0};//存储背包容量为j时能够装下的最大价值
for(int i=1;i<=M;i++)
{
for(int j=N;j>=t[i];j--)
{
F[j]=max(F[j],F[j-t[i]]+v[i]);
/*j-t[i]就是指当前情况去掉某些物品是的有足够空间t[i]恰好装下它,当然很多时候不可能恰恰好,那么F[j-t[i]]中存储的就会是背包内物品总和小于j-t[i]的值,调试易见。处理后发现F[j-t[i]]+v[i]>F[i]那么就会记录下来这个暂时的****最优值*****/
}
}
cout<<F[N]<<endl;
return 0;
}
就这样对于M个物品依次处理,都从最大容积开始 逆推 ,就可以了。一定要逆推,这就是滚动数组。因为我们要保证在处理F[j]=max(F[j],F[j-t[i]]+v[i])时,任意F[j-t[i]]都是先算好了的,否则你就要参看一下背包九讲的另一种方法了