Acwing 背包模型专题打卡
423. 采药
https://www.acwing.com/problem/content/425/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N=105;
int a[N];
int f[1005];
int T,n;
int v[N],w[N];
int main(){
cin>>T>>n;
for(int i=1;i<=n;i++){
cin>>v[i]>>w[i];
}
for(int i=1;i<=n;i++){
for(int j=T;j>=v[i];j--){
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}
cout<<f[T]<<endl;
return 0;
}
// freopen("testdata.in", "r", stdin);
1024. 装箱问题
https://www.acwing.com/problem/content/1026/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N=35;
int a[N];
int f[20010];
int T,n;
int v[N],w[N];
int main(){
cin>>T>>n;
for(int i=1;i<=n;i++){
cin>>v[i];
w[i]=v[i];
}
for(int i=1;i<=n;i++){
for(int j=T;j>=v[i];j--){
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}
cout<<T-f[T]<<endl;
return 0;
}
// freopen("testdata.in", "r", stdin);
1022. 宠物小精灵之收服
https://www.acwing.com/problem/content/1024/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
int N,M,K;
int f[1010][510];
int v1[105],v2[105];
int main(){
cin>>N>>M>>K;
for(int i=1;i<=K;i++){
cin>>v1[i]>>v2[i];
v2[i];
}
for(int i=1;i<=K;i++){
for(int j=N;j>=v1[i];j--){
for(int k=M-1;k>=v2[i];k--){//由于体力0也不行,这里直接-1处理
f[j][k]=max(f[j][k],f[j-v1[i]][k-v2[i]]+1);
}
}
}
int k=M-1;
//逆向推 看看答案是从那个状态转移过来
while(k>0 && f[N][k-1]==f[N][M-1])k--;
cout<<f[N][M-1]<<" "<<M-k<<endl;
return 0;
}
// freopen("testdata.in", "r", stdin);
278. 数字组合
https://www.acwing.com/problem/content/280/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
int a[105];
LL f[10010];
int n,m;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
f[0]=1;
for(int i=1;i<=n;i++){
for(int j=m;j>=a[i];j--){
f[j]+=f[j-a[i]];
}
}
cout<<f[m]<<endl;
return 0;
}
// freopen("testdata.in", "r", stdin);
1023. 买书
https://www.acwing.com/problem/content/1025/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
int a[4]={10,20,50,100};
LL f[1010];
int n,m;
int main(){
cin>>m;
f[0]=1;
for(int i=0;i<4;i++){
for(int j=a[i];j<=m;j++){
f[j]+=f[j-a[i]];
}
}
cout<<f[m]<<endl;
return 0;
}
// freopen("testdata.in", "r", stdin);
532. 货币系统
https://www.acwing.com/problem/content/534/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
int T;
const int N=110;
int a[N];
int f[25010];
int n;
int main(){
cin>>T;
while(T--){
cin>>n;
memset(f,0,sizeof f);
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a,a+n);
int M=a[n-1];
f[0]=1;
int ans=0;
for(int i=0;i<n;i++){
if(!f[a[i]]) ans++;
for(int j=a[i];j<=M;j++){
f[j]=max(f[j],f[j-a[i]]);
}
}
cout<<ans<<endl;
}
return 0;
}
// freopen("testdata.in", "r", stdin);
1019. 庆功会
https://www.acwing.com/problem/content/description/1021/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N=510,M=6010;
int v[N],w[N],s[N];
int f[M];
int n,m;
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>v[i]>>w[i]>>s[i];
}
for(int i=0;i<n;i++){
for(int j=m;j>=0;j--){
for(int k=0;k<=s[i]&&k*v[i]<=j;k++){
f[j]=max(f[j],f[j-k*v[i]]+k*w[i]);
}
}
}
cout<<f[m]<<endl;
return 0;
}
// freopen("testdata.in", "r", stdin);
7. 混合背包问题
https://www.acwing.com/problem/content/7/
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
int N,V;
int dp[1005];
struct Good{
int s,v,w;
};
vector<Good> goods;
int nv,nw,ns;
int main(){
cin>>N>>V;
for(int i=1;i<=N;i++){
cin>>nv>>nw>>ns;
if(ns<=0){
goods.push_back({ns,nv,nw});
}
else {
for(int k=1;k<=ns;k*=2){
ns-=k;
goods.push_back({-1,k*nv,k*nw});
}
if(ns>0){
goods.push_back({-1,ns*nv,ns*nw});
}
}
}
for(auto g:goods){
if(g.s==-1){
for(int j=V;j>=g.v;j--){
dp[j]=max(dp[j],dp[j-g.v]+g.w);
}
}
else {
for(int j=g.v;j<=V;j++){
dp[j]=max(dp[j],dp[j-g.v]+g.w);
}
}
}
cout<<dp[V];
return 0;
}
// freopen("testdata.in", "r", stdin);
8. 二维费用的背包问题
https://www.acwing.com/problem/content/8/
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
int N,V,M;
int v[1005],m[1005],w[1005];
int dp[1005][1005];//用了j体积,k重量的最大价值
int main(){
cin>>N>>V>>M;
for(int i=1;i<=N;i++){
cin>>v[i]>>m[i]>>w[i];
}
for(int i=1;i<=N;i++){
for(int j=V;j>=v[i];j--){
for(int k=M;k>=m[i];k--){
dp[j][k]=max(dp[j][k],dp[j-v[i]][k-m[i]]+w[i]);
}
}
}
cout<<dp[V][M];
return 0;
}
// freopen("testdata.in", "r", stdin);
1020. 潜水员(体积至少是xx的做法)
https://www.acwing.com/problem/content/1022/
状态方程表示与之前体积恰好是xx变成至少是xx即可做此题,同时由于条件变成至少.可以从负数体积状态转移过来,这里所有负数体积都设置为0体积状态(即都不选)
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N=25,M=85;
int f[N][M];//f(i,j)氧气体积至少为i,氮气体积至少为j的最少方案
int n,m,K;
int main(){
cin>>n>>m;
cin>>K;
memset(f,0x3f,sizeof f);
f[0][0]=0;
while(K--){
int a,b,c;
cin>>a>>b>>c;
for(int j=n;j>=0;j--){
for(int k=m;k>=0;k--){//由于状态方程变成 至少 可以从负数体积转移过来 统一吧负数状态设置成0体积
f[j][k]=min(f[j][k],f[max(0,j-a)][max(0,k-b)]+c);
}
}
}
cout<<f[n][m]<<endl;
return 0;
}
// freopen("testdata.in", "r", stdin);
1013. 机器分配
https://www.acwing.com/problem/content/1015/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N=15,M=20;
int a[N][M];
int n,m;
int f[N][M];
int ways[N];
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++){
for(int k=0;k<=j;k++){
f[i][j]=max(f[i][j],f[i-1][j-k]+a[i][k]);
}
}
}
cout<<f[n][m]<<endl;
int j=m;
for(int i=n;i;i--){
for(int k=0;k<=j;k++){
if(f[i][j]==f[i-1][j-k]+a[i][k]){
ways[i]=k;
j-=k;
break;
}
}
}
for(int i=1;i<=n;i++){
cout<<i<<" "<<ways[i]<<endl;
}
return 0;
}
// freopen("testdata.in", "r", stdin);
11. 背包问题求方案数
https://www.acwing.com/problem/content/11/
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
int N,V;
const int mod=1e9+7,INF=1e5;
int v[1005],w[1005],f[1005],dp[1005];
int main(){
cin>>N>>V;
for(int i=1;i<=N;i++){
cin>>v[i]>>w[i];
}
for(int i=1;i<=V;i++){
dp[i]=-INF;
}
f[0]=1;
for(int i=1;i<=N;i++){
for(int j=V;j>=v[i];j--){
int temp=max(dp[j],dp[j-v[i]]+w[i]);
int s=0;
if(temp==dp[j]){
s+=f[j];
}
if(temp==dp[j-v[i]]+w[i]){
s+=f[j-v[i]];
}
if(s>=mod) s-=mod;
dp[j]=temp;
f[j]=s;
}
}
int Maxv=0;
for(int i=0;i<=V;i++){
Maxv=max(Maxv,dp[i]);
}
int res=0;
for(int i=0;i<=V;i++){
if(dp[i]==Maxv){
res+=f[i];
if(res>=mod) res-=mod;
}
}
cout<<res<<endl;
return 0;
}
// freopen("testdata.in", "r", stdin);
12. 背包问题求具体方案
https://www.acwing.com/problem/content/12/
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
int N,V;
const int Maxn=1e3+5;
int w[Maxn],v[Maxn],dp[Maxn][Maxn];
int main(){
cin>>N>>V;
for(int i=1;i<=N;i++){
cin>>v[i]>>w[i];
}
for(int i=N;i>=1;i--){
for(int j=0;j<=V;j++){
dp[i][j]=dp[i+1][j];
if(j>=v[i]){
dp[i][j]=max(dp[i+1][j],dp[i+1][j-v[i]]+w[i]);
}
}
}
for(int i=1;i<=N;i++){
if(dp[i][V]==dp[i+1][V-v[i]]+w[i]){
cout<<i<<" ";
V-=v[i];
}
}
return 0;
}
// freopen("testdata.in", "r", stdin);
487. 金明的预算方案
https://www.acwing.com/problem/content/489/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int, int>PII;
const int N=65,M=32010;
int n,m;
PII father[N];
vector<PII>child[N];
int f[M];
int main(){
cin>>m>>n;
for(int i=1;i<=n;i++){
int v,p,q;
cin>>v>>p>>q;
p*=v;
if(!q){
father[i]={v,p};
}
else child[q].push_back({v,p});
}
for(int i=1;i<=n;i++){
for(int u=m;u>=0;u--){
for(int j=0;j<1<<child[i].size();j++){
int v=father[i].x;//爹必须选
int w=father[i].y;
for(int k=0;k<child[i].size();k++){//二进制枚举
if(j>>k&1){
v+=child[i][k].x;
w+=child[i][k].y;
}
}
if(u>=v) f[u]=max(f[u],f[u-v]+w);
}
}
}
cout<<f[m]<<endl;
return 0;
}
// freopen("testdata.in", "r", stdin);

浙公网安备 33010602011771号