poj 2923 状态压缩 + 01背包
2012-11-29 10:54
337 查看
题意:
两个车有容量a与b,n个物品,每个物品有一个体积,问最小多少次能够运完他们。
因为n<10,所以可以用状态压缩。
先进行遍历,看看1<<n这些状态能不能一次运完。能的话加入it数组里。
然后用it数组,代表物品,进行背包 j代表状态,j&it[i]时,代表两个状态不冲突,就是存在某个物品运了两次。j|it[i]代表当前状态。
两个车有容量a与b,n个物品,每个物品有一个体积,问最小多少次能够运完他们。
因为n<10,所以可以用状态压缩。
先进行遍历,看看1<<n这些状态能不能一次运完。能的话加入it数组里。
然后用it数组,代表物品,进行背包 j代表状态,j&it[i]时,代表两个状态不冲突,就是存在某个物品运了两次。j|it[i]代表当前状态。
#include<stdio.h> #include<string.h> #define Max 10000000 int it[2000],dp[2000],n,ai[20],a,b,sum; int min(int a,int b){ return a<b?a:b; } bool find(int x){ int su=0; bool vis[2000]; memset(vis,0,sizeof(vis)); vis[0]=1; for(int i=0;i<n;i++){ if(1<<i&x){ su+=ai[i]; for(int j=a;j>=ai[i];j--){ if(vis[j-ai[i]]){ vis[j]=1; } } } } if(su>a+b){ return false; } for(int i=0;i<=a;i++){ if(vis[i]&&su-i<=b){ return true; } } return false; } int main(){ int cas; scanf("%d",&cas); int kk=1; int k=0; while(cas--){ k=0; scanf("%d%d%d",&n,&a,&b); for(int i=0;i<n;i++){ scanf("%d",&ai[i]); } for(int i=1;i<(1<<n);i++){ if(find(i)){ it[k++]=i; } } for(int i=0;i<(1<<n);i++){ dp[i]=Max; } dp[0]=0; printf("Scenario #%d:\n",kk++); for(int i=0;i<k;i++){ for(int j=(1<<n)-1;j>=0;j--){ if(dp[j]==Max){ continue; } if((j&it[i])==0){ dp[j|it[i]]=min(dp[j|it[i]],dp[j]+1); } } } printf("%d\n\n",dp[(1<<n)-1]); } return 0; }
相关文章推荐
- POJ 2923 Relocation(01背包变形, 状态压缩DP)
- 解题报告:POJ_2923 Relocation 状态压缩+01背包
- POJ - 2923 (01背包,状态压缩)
- POJ 2923 Relocation(状态压缩DP+DP:01背包)
- POJ 2923 Relocation (状态压缩 0-1背包)
- POJ 2923 Relocation 状态压缩DP + 0-1背包
- poj 2923 Relocation(状态压缩dp+背包)
- POJ 2923 Relocation 状态压缩DP + 0-1背包
- poj 2923 dp状态压缩+背包(两辆货车来运货)
- poj 2923(状态压缩+背包)
- POJ 2923 Relocation (状态压缩+背包)
- POJ 2923 Relocation(状态压缩+背包思想)
- POJ 2923 Relocation 状态DP+01背包
- 01背包状态压缩和记录路径
- POJ-1170 Shopping Offers 状态压缩加背包
- POJ 2923 dp 状态压缩
- uva 624 CD 01背包状态压缩记路径
- POJ 2923 Relocation(状态压缩+ 01背包)
- POJ 2923 Relocation ★(状态压缩+01背包)
- POJ 2923 Relocation(状态压缩+01背包)