背包专题
来源:互联网 发布:企业网站域名备案流程 编辑:程序博客网 时间:2024/05/22 11:33
AC Hdu 2602 Bone Collector 非常常规的01背包问题,用一维和二维数组都可以做,一维快相当多。
#include<stdlib.h>#include<ctype.h>#include<algorithm>#include<vector>#include<string>#include<queue>#include<stack>#include<set>#include<map>#include <string>#include <sstream>using namespace std;int max(int a,int b){ if(a>b) return a; else return b;}int main(){ int t; scanf("%d",&t); int a[1000],c[1000],dp[10000]; while(t--) { int n,v; scanf("%d%d",&n,&v); for(int i=0;i<n;i++) scanf("%d",&a[i]); for(int i=0;i<n;i++) scanf("%d",&c[i]); memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++) for(int j=v;j>=0;j--) { if(j-c[i]>=0) dp[j]=max(dp[j],dp[j-c[i]]+a[i]); } printf("%d\n",dp[v]); }}
AC Poj 3624 Charm Bracelet 赤裸裸的01背包问题。
#include "iostream"#include "math.h"using namespace std;int max(int a,int b){ if(a>b) return a; else return b;}int main(){ int n,m; int a[40000],b[40000]; int dp[40000]; while( cin>>n>>m ) { for(int i=0;i<n;i++) cin>>a[i]>>b[i];memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++) for(int j=m;j>=0;j--) { if(j-a[i]>=0) dp[j]=max(dp[j],dp[j-a[i]]+b[i]); } cout<<dp[m]<<endl; }}
AC Hdu 2546 饭卡 n种菜选若干种使剩下的钱最少,背包容量是开始时的钱,物品体积是菜的价格,状态转移时记录答案。
#include "iostream"#include "cstdlib"#include "cstring"#include "cmath"#include "algorithm"using namespace std;int max(int a,int b){ if(a>b) return a; else return b;}int main(){ int i,j,m,n,a[2000],d[2000]; while( scanf("%d",&n)!=EOF && n ) { for(i=0;i<n;i++) scanf("%d",&a[i]); scanf("%d",&m); sort(a,a+n); memset(d,0,sizeof(d)); if(m>=5) { { for(i=0;i<n-1;i++) for(j=m-5;j>=a[i];j--) { d[j]=max(d[j],d[j-a[i]]+a[i]); } } printf("%d\n",m-d[m-5]-a[n-1]); } else printf("%d\n",m); }}//先计算出m-5块钱在n-1个物品内最多买多少钱的菜,然后再减去最大价格的菜
AC Hdu 2955 Robberies (推荐)抢劫方案最优问题,需要一个简单地转换,我们求的是不被抓的概率而非被抓的概率,各个银行的储蓄总和为背包容量,体积为单个银行 的储蓄,价值为不被抓概率。
#include "iostream"#include "cstdlib"#include "cstring"#include "cmath"#include "algorithm"using namespace std;int max(int a,int b){ if(a>b) return a; else return b;}double p;int n,t,sum;int m[1000];double q[1000];double dp[10000];int main(){ scanf("%d",&t); while(t--) { int ss; sum=0; scanf("%lf %d",&p,&n); for(int i=0;i<n;i++) { scanf("%d%lf",&m[i],&q[i]); q[i]=1.0-q[i]; sum+=m[i]; } memset(dp,0,sizeof(dp)); dp[0]=1; for(int i=0;i<n;i++) for(int j=sum;j>=0;j--) { if(j-m[i]>=0) dp[j]=max(dp[j],dp[j-m[i]]*q[i]); } for(int i=0;i<=sum;i++) { int big=-1; if( dp[i]>big && ( dp[i]>=(1-p)) ) { big=dp[i]; ss=i; } } printf("%d\n",ss); } }
AC Poj 2184 Cow Exhibition(推荐)变形的01背包,其实问题的本质是保证智商和幽默感和不为负数情况下的最大和。智商属性体积,幽默感属性为价值,问题转换为求体积大等于0时的体积、价值总和。
#include "stdio.h"#include "stdlib.h"#include "algorithm"#include "iostream"#include "math.h"#include "string.h"using namespace std;#define max(a,b) ((a)>(b)?(a):(b)) int a[110],b[110];int dp[200000];int main(){int n;int t=10000;while(scanf("%d",&n)!=EOF ){for(int i=0;i<n;i++)scanf("%d%d",&a[i],&b[i]);memset(dp,-10000,sizeof(dp));dp[t]=0;for(int i=0;i<n;i++){if(a[i]<0 && b[i]<0 )continue ;else if(a[i]>0){for(int j=199999;j>=a[i];j--)dp[j]=max(dp[j-a[i]]+b[i],dp[j]);}else{for(int j=0;j<200000+a[i];j++)dp[j]=max(dp[j-a[i]]+b[i],dp[j]);}}int ans=0;for(int i=t;i<200000;i++)if(dp[i]>0)ans=max(ans,i-t+dp[i]);printf("%d\n",ans);}return 0;}
AC Hdu 3466 Proud Merchants 与顺序有关的01背包,先按q-p排序再来处理,难想容易敲。
#include<stdio.h>#include<iostream>#include<math.h>#include<stdlib.h>#include<ctype.h>#include<algorithm>#include<vector>#include<string>#include<queue>#include<stack>#include<set>#include<map>#include <string>#include <sstream>using namespace std;int dp[100000];int max (int a,int b){ if (a>b ) return a ; else return b;}struct Ac{ int p; int q; int v;}ac[1000000];bool cmp(Ac ss ,Ac sss){ return ( ss.q-ss.p ) < ( sss.q- sss.p ) ; }int main(){ int n,m; int t,s ,k; while(scanf("%d%d",&n,&m)!=EOF ) { for(int i=0;i<n;i++) scanf("%d%d%d",&ac[i].p,&ac[i].q,&ac[i].v); memset(dp,0,sizeof(dp)); sort(ac,ac+n,cmp); for (int i=0;i<n;i++) for (int j=m;j>=0;j--) { if ( j-ac[i].q>=0 ) dp[j]=max (dp[j],dp[j-ac[i].p]+ac[i].v); } printf("%d\n",dp[m]); } return 0;}
AC Hdu 1114 Piggy-Bank 简单多重背包,但当成01背包来暴力也完全没有问题
#include "iostream"#include "cstdlib"#include "cstring"#include "cmath"#include "algorithm"using namespace std;int min(int a,int b){ if(a>b) return b; else return a;}int main(){ int t,ok,k; int e,f,n,s; int p[1000],w[1000],dp[10000]; scanf("%d",&t); while(t--) { scanf("%d%d",&e,&f); scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d%d",&p[i],&w[i]); memset(dp,1000000,sizeof(dp)); dp[0]=0; s=f-e; ok=0; for(int i=0;i<n;i++) for(int j=0;j<=s;j++) { if(j-w[i]>=0) dp[j]=min(dp[j],dp[j-w[i]]+p[i]); } if(dp[s]!=1000000 && dp[s]<1000000) printf("The minimum amount of money in the piggy-bank is %d.\n",dp[s]); else printf("This is impossible.\n"); }}
AC Hdu 1059 Dividing 简单多重背包,体积为硬币数,价值为币值,可用二进制处理成01背包求解,可用30对num进行优化。
//多重背包//HDU 1059//题意:价值分别为1,2,3,4,5,6的物品的个数分别为 a[1],a[2],````a[6]//问能不能分成两堆价值相等的 #include<stdio.h>#include<string.h>int a[7];int f[120005];int v,k;void ZeroOnePack(int cost,int weight)//cost 为费用, weight 为价值 { for(int i=v;i>=cost;i--) if(f[i-cost]+weight>f[i]) f[i]=f[i-cost]+weight;} void CompletePack(int cost,int weight){ for(int i=cost;i<=v;i++) if(f[i-cost]+weight>f[i]) f[i]=f[i-cost]+weight;} void MultiplePack(int cost ,int weight,int amount){ if(cost*amount>=v) CompletePack(cost,weight); else { for(int k=1;k<amount;) { ZeroOnePack(k*cost,k*weight); amount-=k; k<<=1; } ZeroOnePack(amount*cost,amount*weight); } } int main(){ int tol; int iCase=0; while(1) { iCase++; tol=0; for(int i=1;i<7;i++) { scanf("%d",&a[i]); tol+=a[i]*i;//总价值数 } if(tol==0) break; if(tol%2==1) { printf("Collection #%d:\nCan't be divided.\n\n",iCase); continue; } else { v=tol/2; memset(f,0,sizeof(f)); for(int i=1;i<7;i++) MultiplePack(i,i,a[i]); if(f[v]==v) printf("Collection #%d:\nCan be divided.\n\n",iCase); else printf("Collection #%d:\nCan't be divided.\n\n",iCase); } } return 0; }
AC Hdu 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 标题超长超简单的多重背包,可用01背包求解。
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int INF = 0x3f3f3f3f; int n,m; int c[110],w[110],num[110],dp[110]; void ZeroOnePack(int cost, int weight) { for(int i = n; i >= cost; i--) dp[i] = max(dp[i],dp[i-cost]+weight); } void CompletePack(int cost, int weight) { for(int i = cost; i <= n; i++) dp[i] = max(dp[i],dp[i-cost]+weight); } void MultiplePack(int cost, int weight, int amount) { if(cost * amount >= n) { CompletePack(cost,weight); } else { int k = 1; while(k < amount) { ZeroOnePack(k*cost,k*weight); amount -= k; k = k << 1; } ZeroOnePack(amount*cost,amount*weight); } } int main() { int test; scanf("%d",&test); while(test--) { scanf("%d %d",&n,&m); for(int i = 1; i <= m; i++) { scanf("%d %d %d",&c[i],&w[i],&num[i]); } memset(dp,0,sizeof(dp)); for(int i = 1; i <= m; i++) { MultiplePack(c[i],w[i],num[i]); } printf("%d\n",dp[n]); } return 0; }
0 0
- 背包专题
- 背包专题
- 背包专题、
- 背包专题
- 【背包专题】01背包
- 【背包专题】01背包
- POJ 多重背包专题
- 01 背包 专题
- 01背包专题
- Training:背包专题
- 分组背包专题小结
- 01背包专题
- 【背包专题汇总】
- DP专题->01背包
- 【专题】背包问题
- 2016背包专题1005
- 2016背包专题1010
- 2016背包专题1008
- 静态链接库和动态连接库使用
- mybatis---关联表的增删改三种方式
- 求n个字符的全排列
- [Linux]RedHat Linux 忘记root密码该如何重新设置密码
- JAVA关键字总结(整理后最全最详细)
- 背包专题
- NYOJ 22 素数求和问题
- shell脚本—从Server服务端给另外的Client端执行添加用户命令
- 二维数组:内存布局与指针
- Android开发过程看4.0AVD无法创建
- 未能从程序集“System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”中加载类型“
- android.util.AndroidRuntimeException: requestFeature() must be called before adding content
- 【141029】Visual C++开发答疑300问+随书光盘源码
- 稀疏模型与结构性稀疏模型 及ADMM求解