USACO 5.3 Milk Measuring(迭代深搜+DP)
像是背包的逆问题,给一个体积,然后给一些物品,求用最少的物品组成这个体积,输出字典序最小的集合。
物品和体积都不小,完全没什么思路,印象中DD大神的背包9讲里,有USACO里背包问题的解析,然后发现暴力然后DP就可以过,然后。。。就水过了。。
1 /* 2 ID: cuizhe 3 LANG: C++ 4 TASK: milk4 5 */ 6 #include <cstdio> 7 #include <cstring> 8 #include <cmath> 9 #include <algorithm> 10 #include <iostream> 11 using namespace std; 12 int v; 13 int p[101]; 14 int o[101]; 15 int que[101]; 16 int dp[20001]; 17 int t,n; 18 int dfs(int x) 19 { 20 int i,j; 21 if(x == 0) 22 { 23 for(i = 1;i <= v;i ++) 24 dp[i] = 0; 25 for(i = 1;i <= t;i ++) 26 { 27 for(j = p[que[i]];j <= v;j ++) 28 dp[j] = max(dp[j],dp[j-p[que[i]]]+p[que[i]]); 29 } 30 if(dp[v] == v) 31 return 1; 32 else 33 return 0; 34 } 35 for(i = 1;i <= n;i ++) 36 { 37 if(!o[i]) 38 { 39 o[i] = 1; 40 que[x] = i; 41 if(dfs(x-1)) 42 return 1; 43 o[i] = 0; 44 } 45 } 46 return 0; 47 } 48 int main() 49 { 50 int i,j; 51 freopen("milk4.in","r",stdin); 52 freopen("milk4.out","w",stdout); 53 scanf("%d%d",&v,&n); 54 for(i = 1;i <= n;i ++) 55 scanf("%d",&p[i]); 56 sort(p+1,p+n+1); 57 for(i = 1;i <= n-1;i ++) 58 { 59 memset(o,0,sizeof(o)); 60 t = i; 61 if(dfs(i)) 62 break; 63 } 64 printf("%d",i); 65 if(i == n) 66 { 67 for(i = 1;i <= n;i ++) 68 printf(" %d",p[i]); 69 } 70 else 71 { 72 for(j = i;j >= 1;j --) 73 printf(" %d",p[que[j]]); 74 } 75 printf("\n"); 76 return 0; 77 }