码迷,mamicode.com
首页 > 其他好文 > 详细

状态压缩

时间:2015-02-17 23:31:55      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:

题目描述:

编号为0~n-1的n个位置上分别有价值为w[0]~w[n-1]的n个物品,现在要选出一些物品,使得获得的价值最大,约束条件是:任意连续的m个物品中选取的物品数量不超过q。其中n<=1000, 2<=m<=10, 1<=q<=m, w[i]<=100.

算法分析:

状态定义:

dp[i][s]表示:解决了物品0~i的选取问题,物品i-m+1, i-m+2, ..., i 的选取状态为s时,所获得的最大价值, 其中s的第0, 1, ..., m-1位分别指示物品i-m+1, i-m+2, ..., i的选取情况,对应位为1表示选取,为0表示不选取。

状态转移:

1.如果bitcnt(s)>q, 那么由s不可能转移出任何有效状态.

2.如果bitcnt(s)<=q, 那么此时分为两种情况(设下一状态为ns):

  a.当不选取下一个物品时,ns=s>>1, 有转移方程:dp[i+1][ns] = max(dp[i+1][ns], dp[i][s]);

  b.当选取下一个物品时,ns=(s>>1)+(1<<(m-1)), 在bitcnt(ns)<=q的条件下,有转移方程:dp[i+1][ns] = max(dp[i+1][ns], dp[i][s]+w[i+1]).

我的代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 #define MAXN 1100
 6 
 7 int w[MAXN], dp[MAXN][MAXN];
 8 
 9 int bitcnt(int x)
10 {
11     int cnt = 0;
12     while(x)
13     {
14         if(x&1)    ++cnt;
15         x = x>>1;
16     }
17     return cnt;
18 }
19 
20 int main()
21 {
22     int n, m, q, ans;
23     while(scanf("%d%d%d", &n, &m, &q)!=EOF)
24     {
25         for(int i=0; i<n; ++i)
26             scanf("%d", &w[i]);
27         ans = 0;
28         if(n<m)
29         {
30             for(int s=0; s<(1<<n); ++s)
31             {
32                 if(bitcnt(s)<=q)
33                 {
34                     int sum=0;
35                     for(int j=0; j<n; ++j) if((s>>j)&1) sum += w[j];
36                     ans = max(ans, sum);
37                 }
38             }
39             printf("%d\n", ans);
40             return 0;
41         }
42         
43         memset(dp, 0, sizeof(dp));
44         for(int s=0; s<(1<<m); ++s)
45         {
46             if(bitcnt(s)>q) continue;
47             int sum = 0;
48             for(int j=0; j<m; ++j) if((s>>j)&1) sum += w[j];
49             dp[m-1][s] = sum;
50         }
51         for(int i=m-1; i<n-1; ++i)
52         {
53             for(int s=0; s<(1<<m); ++s)
54             {
55                 int bcnt = bitcnt(s);
56                 int ns;
57                 if(bcnt>q) continue;
58                 ns = s>>1;
59                 dp[i+1][ns] = max(dp[i+1][ns], dp[i][s]);
60                 ns = (s>>1)+(1<<(m-1));
61                 bcnt = bitcnt(ns);
62                 if(bcnt>q) continue;
63                 dp[i+1][ns] = max(dp[i+1][ns], dp[i][s]+w[i+1]);
64             }
65         }
66         for(int s=0; s<(1<<m); ++s) ans = max(ans, dp[n-1][s]);
67         printf("%d\n", ans);
68     }
69     return 0;
70 }

 

题目来源:http://hihocoder.com/problemset/problem/1044?sid=252822

 

状态压缩

标签:

原文地址:http://www.cnblogs.com/pczhou/p/4295514.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!