01背包
来源:互联网 发布:如何用信用卡支付淘宝 编辑:程序博客网 时间:2024/06/06 06:28
滚动数组:
dp[j]=max(dp[j],dp[j-w]+v);
POJ 2184
将数组扩大100000,负数变为正数来处理
#include <iostream>#include <cstring>#include <string>#include <cstdio>using namespace std;#define inf 0x3f3f3f3ftypedef long long ll;const int maxn=2e5+10;int n,dp[maxn],s[1000],f[1000];int main(){ while(scanf("%d",&n)!=EOF) { for(int i=0;i<n;i++) cin >> s[i] >> f[i]; for(int i=0;i<maxn;i++) dp[i]=-inf; dp[100000]=0; for(int i=0;i<n;i++) { if(s[i]<0&&f[i]<0) continue; if(s[i]>0) { for(int j=200000;j>=s[i];j--) dp[j]=max(dp[j-s[i]]+f[i],dp[j]); } else { for(int j=s[i];j<=200000+s[i];j++) dp[j]=max(dp[j-s[i]]+f[i],dp[j]); } } int ans=0; for(int i=100000;i<=200000;i++) if(dp[i]>=0) ans=max(ans,dp[i]+i-100000); cout << ans << endl; } return 0;}
POJ 2923
题意:有n种货物,有两辆车分别可以装C1,C2重量的货物,每次都必须两辆一起运送,问最少运送次数。
状压枚举出可以两辆车一次运完的状态,状压01.
#include <iostream>#include <string>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define inf 0x3f3f3f3ftypedef long long ll;const int maxn=1<<11;int dp[maxn],state[maxn],c[15],n,c1,c2,vis[maxn];bool check(int x){ memset(vis,0,sizeof(vis)); vis[0]=1; int sum=0; for(int i=0;i<n;i++) { if((x>>i)&1) { sum+=c[i]; for(int j=c1;j>=c[i];j--) if(vis[j-c[i]]) vis[j]=1; } } for(int i=0;i<=c1;i++) if(vis[i]&&sum-i<=c2) return true; return false;}int main(){ int t,num=1; cin >> t; while(t--) { cin >> n >> c1 >> c2; for(int i=0;i<n;i++) cin >> c[i]; int cnt=0,maxm=(1<<n)-1; for(int i=1;i<=maxm;i++) if(check(i)) state[cnt++]=i; for(int i=0;i<maxn;i++) dp[i]=inf; dp[0]=0; for(int i=0;i<cnt;i++) { for(int j=maxm-state[i];j>=0;j--) if(!(state[i]&j)) dp[state[i]|j]=min(dp[state[i]|j],dp[j]+1); } printf("Scenario #%d:\n%d\n\n",num++,dp[maxm]); } return 0;}
HDU 2546
先将钱数-5,再将最贵的拿出来被5减掉,然后对剩余的进行01
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <string>using namespace std;typedef long long ll;const int maxn=1e3+10;int dp[maxn],d[maxn],n,m;int main(){ while(scanf("%d",&n)!=EOF) { if(n==0) break; int sum=0; for(int i=0;i<n;i++) cin >> d[i],sum+=d[i]; cin >> m; sort(d,d+n); if(m<5) { cout << m << endl; continue; } if(sum<=m-5) { cout << m-sum << endl; continue; } int res=m-5,x=5-d[n-1]; memset(dp,0,sizeof(dp)); for(int i=0;i<n-1;i++) { for(int j=res;j>=d[i];j--) { if(dp[j-d[i]]+d[i]>res) continue; dp[j]=max(dp[j],dp[j-d[i]]+d[i]); } } cout << res-dp[res]+x << endl; }}
HDU 2639
求第K优解的01
#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <cstdio>using namespace std;#define inf 0x3f3f3f3f#define PI acos(-1.0)typedef long long ll;const int maxn=1e3+10;int dp[maxn][35],v[maxn],d[maxn],V,K,a[maxn],b[maxn],n;int main(){ int t; cin >> t; while(t--) { cin >> n >> V >> K; for(int i=1;i<=n;i++) cin >> d[i]; for(int i=1;i<=n;i++) cin >> v[i]; memset(dp,0,sizeof(dp)); int k; for(int i=1;i<=n;i++) { for(int j=V;j>=v[i];j--) { for(k=1;k<=K;k++) { a[k]=dp[j][k]; b[k]=dp[j-v[i]][k]+d[i]; } a[k]=-1,b[k]=-1; int x=1,y=1,z=1; while(z<=k&&(a[x]!=-1||b[y]!=-1)) { if(a[x]>b[y]) dp[j][z]=a[x++]; else dp[j][z]=b[y++]; if(dp[j][z]!=dp[j][z-1]) z++; } } } cout << dp[V][K] << endl; } return 0;}
HDU 2126
求最优方案总数
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <string>using namespace std;typedef long long ll;const int maxn=510;int dp[maxn],g[maxn],n,m,v[maxn];int main(){ int t; cin >> t; while(t--) { cin >> n >> m; for(int i=0;i<n;i++) cin >> v[i]; for(int i=0;i<=m;i++) g[i]=1; memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++) { for(int j=m;j>=v[i];j--) { if(dp[j]<dp[j-v[i]]+1) dp[j]=dp[j-v[i]]+1,g[j]=g[j-v[i]]; else if(dp[j]==dp[j-v[i]]+1) g[j]=g[j-v[i]]+g[j]; } } if(dp[m]) { printf("You have %d selection(s) to buy with %d kind(s) of souvenirs.\n",g[m],dp[m]); } else printf("Sorry, you can't buy anything.\n"); } return 0;}
UVA 624
记录01背包的路径
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int maxn=1e4+10;int dp[maxn],v[30],vis[30][maxn],n,m;int main(){ while(scanf("%d",&m)!=EOF) { cin >> n; for(int i=0;i<n;i++) cin >> v[i]; memset(dp,0,sizeof(dp)); memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++) { for(int j=m;j>=v[i];j--) { if(dp[j]<=dp[j-v[i]]+v[i]) dp[j]=dp[j-v[i]]+v[i],vis[i][j]=1; } } int k=m; for(int i=n;i>=0;i--) { if(vis[i][k]) { cout << v[i] << " "; k-=v[i]; } } cout << "sum:" << dp[m] << endl; } return 0;}
阅读全文
0 0
- 【背包专题】01背包
- 01背包,完全背包
- 01背包 完全背包
- 01背包/完全背包
- 01背包,完全背包
- 背包问题---01背包
- 背包入门--01背包
- 【背包专题】01背包
- 01背包,完全背包
- 01背包,完全背包, 多重背包
- 01背包,完全背包,多重背包
- 01背包、完全背包、多重背包详解
- 01背包,完全背包,多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包模板
- 递归排序
- 判断Activity是否在运行?
- java并发编程实战-并发程序的测试
- jquery源码解析(第3章元素之偏移算法)
- 关于安全删除Arraylist中的一组节点
- 01背包
- hadoop 2.x安装:完全分布式安装
- 根据路径获得图片并压缩,返回bitmap用于显示
- fzu 2278 YYS [第八届福建省大学生程序设计竞赛 Problem G] [概率]
- 《精通ASP.NET MVC5》读书笔记
- python api获取与分析
- HDU1007-Quoit Design(求最近点对,求最远点对(凸包+旋转卡壳))
- Date类,Calendar类,DateFormat类,SimpleDateFormat类
- 【JZOJ2702】探险