1 solutions
-
1
题意
一个要求凑满的01背包,凑不满就输出最大化价值的体积。
思路
首先先把01背包写好。如果01不熟的可以先把采药之类的题目A掉再回来。
然后就是爆改。
首先我们要怎样标记凑不出来呢?
凑不出来有两种情况:
- 没有触及。
- 被凑不出来的触及。
为什么感觉有点像递归啊喂!
所以我们初始化为负无限,不可触及就会保留负无限。
那如果被凑不出来的碰了呢?很简单,加一个特判,如果碰完发现它还是负数,说明碰它的是负无限,就把它标回负无限。
最后判断一下,如果答案为负数就找最大。
代码
#include<iostream> #define maxs 0x7fffffff//好看,主要是为了好看。 using namespace std; int f[int(2e6)];//有点大,开在外面 int main(){ int n(0),v(0); cin>>n>>v; struct{int v;int w;}a[n+1];//清爽的a for(int i(1);i<=n;i++) cin>>a[i].v; //最讨厌它分开的一集 --|二二二二二二> for(int i(1);i<=n;i++) cin>>a[i].w; fill(f,&f[v+1],-maxs);//标最大值,以区分价值为0和无法凑出的区别。 f[0]=0;//空间为0就当然没有价值啦^_^ for(int i(1);i<=n;i++)//状态永远是被压掉的内个,状态放外面 for(int j(v);j>0;j--) /*观察二维的状态转移方程得知,需要使用前面的,所以前面的暂时不能改。*/ if(j>=a[i].v){//如果塞得下 f[j]=max(f[j],f[j-a[i].v]+a[i].w);//看看谁比较大 if(f[j]<0) f[j]=-maxs; /*无限永恒!(bushi)其实是为了防止屡次上升变成非负数。*/ } if(f[v]>=0)//凑得出来 cout<<f[v]; else{//凑不出来就会保持原来的无限 int maxn(-maxs),maxi(0); for(int i(1);i<=v;i++)//这还要教就回去练<<A+B problem>>吧。 if(f[i]>maxn){ maxn=f[i]; maxi=i; } cout<<maxi; } }
- 1
Information
- ID
- 1102
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 8
- Tags
- (None)
- # Submissions
- 40
- Accepted
- 7
- Uploaded By