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 }

 

posted @ 2013-05-24 09:37  Naix_x  阅读(258)  评论(0编辑  收藏  举报