01背包
Charm Bracelet http://poj.org/problem?id=3624
01背包模板题带空间复杂度优化的。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int M=20010; 7 int n,v,dp[M],c[M],w[M]; 8 void ZeroOnePack(int cost,int weight){ 9 for(int i=v;i>=cost;i--){ 10 dp[i]=max(dp[i],dp[i-cost]+weight); 11 } 12 } 13 int main(){ 14 while(~scanf("%d%d",&n,&v)){ 15 for(int i=1;i<=n;i++){ 16 scanf("%d%d",&c[i],&w[i]); 17 } 18 mt(dp,0); 19 for(int i=1;i<=n;i++){ 20 ZeroOnePack(c[i],w[i]); 21 } 22 printf("%d\n",dp[v]); 23 } 24 return 0; 25 }
饭卡 http://acm.hdu.edu.cn/showproblem.php?pid=2546
电子科大的饭卡5块可买50块的菜,我要转学。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int M=1024; 7 int w[M],dp[M]; 8 int n,v; 9 void ZeroOnePack(int cost,int weight){ 10 for(int i=v;i>=cost;i--){ 11 dp[i]=max(dp[i],dp[i-cost]+weight); 12 } 13 } 14 int main(){ 15 while(~scanf("%d",&n),n){ 16 for(int i=1;i<=n;i++){ 17 scanf("%d",&w[i]); 18 if(w[i]>w[1]) swap(w[1],w[i]); 19 } 20 scanf("%d",&v); 21 if(v<5){ 22 printf("%d\n",v); 23 continue; 24 } 25 v-=5; 26 mt(dp,0); 27 for(int i=2;i<=n;i++){ 28 ZeroOnePack(w[i],w[i]); 29 } 30 printf("%d\n",v+5-dp[v]-w[1]); 31 } 32 return 0; 33 }
Robberies http://acm.hdu.edu.cn/showproblem.php?pid=2955
01背包:每个物品代价是每个银行钱的数目,物品的价值是在该银行不被抓的概率 (1-被抓概率),背包容量是所有银行钱的总和。01背包求dp[i]表示获得i的钱不被抓的最大概率。最后从大到小枚举出 dp[i]>=(1-P)这个i就是答案了。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int M=100010; 7 int t,n,v,c[M]; 8 double w[M],dp[M]; 9 void ZeroOnePack(int cost,double weight){ 10 for(int i=v;i>=cost;i--){ 11 dp[i]=max(dp[i],dp[i-cost]*weight); 12 } 13 } 14 int main(){ 15 double tmp; 16 while(~scanf("%d",&t)){ 17 while(t--){ 18 scanf("%lf%d",&tmp,&n); 19 v=0; 20 for(int i=1;i<=n;i++){ 21 scanf("%d%lf",&c[i],&w[i]); 22 v+=c[i]; 23 w[i]=1-w[i]; 24 } 25 mt(dp,0); 26 dp[0]=1; 27 for(int i=1;i<=n;i++){ 28 ZeroOnePack(c[i],w[i]); 29 } 30 for(int i=v;i>=0;i--){ 31 if(dp[i]>=(1-tmp)){ 32 printf("%d\n",i); 33 break; 34 } 35 } 36 } 37 } 38 return 0; 39 }
Bone Collector http://acm.hdu.edu.cn/showproblem.php?pid=2602
模板题
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int M=1024; 7 int w[M],c[M]; 8 int dp[M]; 9 int main(){ 10 int t,n,v; 11 while(~scanf("%d",&t)){ 12 while(t--){ 13 scanf("%d%d",&n,&v); 14 for(int i=1;i<=n;i++){ 15 scanf("%d",&w[i]); 16 } 17 for(int i=1;i<=n;i++){ 18 scanf("%d",&c[i]); 19 } 20 mt(dp,0); 21 for(int i=1;i<=n;i++){ 22 for(int j=v;j>=c[i];j--){ 23 dp[j]=max(dp[j],dp[j-c[i]]+w[i]); 24 } 25 } 26 printf("%d\n",dp[v]); 27 } 28 } 29 return 0; 30 }
Bone Collector II http://acm.hdu.edu.cn/showproblem.php?pid=2639
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int M=128; 7 int dp[M<<3][32];//dp[i][j]表示容量为i,第j大的值 8 int c[M],w[M],a[32],b[32]; 9 int main() { 10 int t,n,v,K; 11 scanf("%d",&t); 12 while(t--) { 13 scanf("%d%d%d",&n,&v,&K); 14 for(int i=1;i<=n;i++){ 15 scanf("%d",&w[i]); 16 } 17 for(int i=1;i<=n;i++){ 18 scanf("%d",&c[i]); 19 } 20 mt(dp,0); 21 for(int i=1;i<=n;i++){ 22 for(int j=v;j>=c[i];j--){ 23 for(int k=1;k<=K;k++){ 24 a[k]=dp[j][k]; 25 b[k]=dp[j-c[i]][k]+w[i]; 26 } 27 int x=1,y=1,z=1; 28 a[K+1]=b[K+1]=-1; 29 while(z<=K&&(x<=K||y<=K)){ 30 if(a[x]>b[y]) dp[j][z]=a[x++]; 31 else dp[j][z]=b[y++]; 32 if(dp[j][z]!=dp[j][z-1]) z++; 33 } 34 } 35 } 36 printf("%d\n",dp[v][K]); 37 } 38 return 0; 39 }
end