动态规划

重新学习动规,又有了新的体会

0-1背包

每种物品只取一次

不优化的表达式是 f[i][j]=max{f[i-1[j],f[i-1][j-w[i]]+c[i]};

f[i][j]与前一行有关所以可以用滚动数组优化(随时更新)

空间优化 滚动数组法

改进后方程 f[j]=max(f[j],f[j-w[i]]+c[i]);

代码如下:

#include<bits/stdc++.h>

#define M 2000

using namespace std;

int n,m,w[M],c[M];

int f[M];

int main(){

cin>>m>>n;

for(int i=1;i<=n;i++){

cin>>w[i]>>c[i];

}

for(int i=1;i<=n;i++){

for(int j=m;j>=w[i];j--){//切记是倒叙 重量从大到小枚举

f[j]=max(f[j],f[j-w[i]]+c[i]);

}

}

cout<<f[m];

}

 

 

完全背包

数量无限

01背包滚动数组重量循环(j)的顺序相反;

for(int i=1;i<=n;i++){

for(int j=w[i];j>=m;j++){ f[j]=max(f[j],f[j-w[i]]+c[i]);

}

}

 

 

2022 8.2

 

 

P2639 [USACO09OCT]Bessie's Weight Problem G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

01背包

 

//其实刚开始做这道题时,我以为这和01背包不一样——毕竟只有体积而没有价值。

//但是——我再去想它和01背包有什么相同点时,我发现:只不过01背包是在体积满足时找最大价值,而这道题是在体积满足时找最大体积。

 

//那么问题来了:假如我们换个思路,将这道题的每个干草也赋予它自己的价值,那岂不是变得和01背包一模一样了??

//那我们赋予每一个干草的价值是什么呢??答案显而易见:就是它自己的体积!!

 

 

#include<bits/stdc++.h>

#define M 1000001

 

using namespace std;

 

int n,m;

int w[M],c[M];

int f[M];

int main()

{

cin>>m>>n;

for(int i=1;i<=n;i++){

cin>>w[i];

c[i]=w[i];  //不同之处:直接赋值而非输入!

}

for(int i=1;i<=n;i++){

for(int j=m;j>=w[i];j--){

f[j]=max(f[j],f[j-w[i]]+c[i]);

}

}

cout<<f[m];

}

 

 

 

多重背包

信息学奥赛一本通(C++版)在线评测系统 (ssoier.cn)

例题庆功会 转化成01背包进行求解

滚动数组法

 

#include<iostream>

#include<cmath>

#define N 10001

using namespace std;

int n,m;

int s[N],w[N],f[N],c[N] ;

int main(){

cin>>n>>m;

for(int i=1;i<=n;i++)

cin>>w[i]>>c[i]>>s[i];

 

 for(int i=1;i<=n;i++)

for(int j=1;j<=s[i];j++) //s[i]个物品是i的01背包

for(int k=m;k>=w[i];k--)

f[k]=max(f[k],f[k-w[i]]+c[i]);

cout<<f[m];

} 

 

posted on 2022-08-20 21:41  ljq0120  阅读(7)  评论(0编辑  收藏  举报