首页 > 代码库 > 状态压缩DP
状态压缩DP
1:POJ 炮兵阵地
预先处理好情况,然后又类似格子取数的状压。
我们用DP[I][J][K]表示处理第I个格子,I-1格子的状态为J,I-2的格子为K,然后转移
1 #include<stdio.h>
2 #include<string.h>
3 #include<algorithm>
4 #include<math.h>
5 #include<vector>
6 using namespace std;
7 char s[123][123];
8 int n,m,dp[123][123][123];
9 int ok[12345],mp[123][123];
10 vector<int>v[123];
11 int t;
12 int cal(int x)//计算能放的数量
13 {
14 int ans=0;
15 while (x){
16 if (x&1) ans++;
17 x/=2;
18 }
19 return ans;
20 }
21
22 void init()//预处理
23 {
24 t=0;
25 for (int i=0;i<(1<<m);i++)
26 {
27 if ((i<<1)&i) continue;
28 if ((i<<2)&i) continue;
29 ok[t++]=i;
30 }
31 for (int i=0;i<n;i++)
32 {
33 v[i].clear();
34 for (int j=0;j<t;j++)
35 {
36 int flag=1;
37 int top=0;
38 for (int k=0;k<m;k++)
39 if (s[i][k]==‘H‘&&(ok[j]&(1<<k)))
40 {
41 flag=0;
42 break;
43 }
44 if (flag) v[i].push_back(ok[j]);
45 }
46 }
47 }
48
49 int main()
50 {
51 while (scanf("%d%d",&n,&m)!=EOF)
52 {
53 for (int i=0;i<n;i++) scanf("%s",s[i]);
54 init();
55 memset(dp,-1,sizeof(dp));
56 for (int i=0;i<v[0].size();i++) dp[0][i][0]=cal(v[0][i]);//处理1,2行的情况
57 for (int i=0;i<v[0].size();i++)
58 for (int j=0;j<v[1].size();j++)
59 if (!(v[0][i]&v[1][j])&&dp[0][i][0]!=-1) dp[1][j][i]=dp[0][i][0]+cal(v[1][j]);
60
61 for (int i=2;i<n;i++)
62 for (int j=0;j<v[i].size();j++)
63 for (int k=0;k<v[i-1].size();k++){
64 if (v[i][j]&v[i-1][k]) continue;
65 for (int p=0;p<v[i-2].size();p++)
66 if (dp[i-1][k][p]!=-1&&(v[i][j]&v[i-2][p])==0)
67 dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][p]+cal(v[i][j]));
68 }
69 int ans=0;
70 for (int i=0;i<t;i++)
71 for (int j=0;j<t;j++)
72 ans=max(ans,dp[n-1][i][j]);
73 printf("%d\n",ans);
74 }
75 return 0;
76 }
2 #include<string.h>
3 #include<algorithm>
4 #include<math.h>
5 #include<vector>
6 using namespace std;
7 char s[123][123];
8 int n,m,dp[123][123][123];
9 int ok[12345],mp[123][123];
10 vector<int>v[123];
11 int t;
12 int cal(int x)//计算能放的数量
13 {
14 int ans=0;
15 while (x){
16 if (x&1) ans++;
17 x/=2;
18 }
19 return ans;
20 }
21
22 void init()//预处理
23 {
24 t=0;
25 for (int i=0;i<(1<<m);i++)
26 {
27 if ((i<<1)&i) continue;
28 if ((i<<2)&i) continue;
29 ok[t++]=i;
30 }
31 for (int i=0;i<n;i++)
32 {
33 v[i].clear();
34 for (int j=0;j<t;j++)
35 {
36 int flag=1;
37 int top=0;
38 for (int k=0;k<m;k++)
39 if (s[i][k]==‘H‘&&(ok[j]&(1<<k)))
40 {
41 flag=0;
42 break;
43 }
44 if (flag) v[i].push_back(ok[j]);
45 }
46 }
47 }
48
49 int main()
50 {
51 while (scanf("%d%d",&n,&m)!=EOF)
52 {
53 for (int i=0;i<n;i++) scanf("%s",s[i]);
54 init();
55 memset(dp,-1,sizeof(dp));
56 for (int i=0;i<v[0].size();i++) dp[0][i][0]=cal(v[0][i]);//处理1,2行的情况
57 for (int i=0;i<v[0].size();i++)
58 for (int j=0;j<v[1].size();j++)
59 if (!(v[0][i]&v[1][j])&&dp[0][i][0]!=-1) dp[1][j][i]=dp[0][i][0]+cal(v[1][j]);
60
61 for (int i=2;i<n;i++)
62 for (int j=0;j<v[i].size();j++)
63 for (int k=0;k<v[i-1].size();k++){
64 if (v[i][j]&v[i-1][k]) continue;
65 for (int p=0;p<v[i-2].size();p++)
66 if (dp[i-1][k][p]!=-1&&(v[i][j]&v[i-2][p])==0)
67 dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][p]+cal(v[i][j]));
68 }
69 int ans=0;
70 for (int i=0;i<t;i++)
71 for (int j=0;j<t;j++)
72 ans=max(ans,dp[n-1][i][j]);
73 printf("%d\n",ans);
74 }
75 return 0;
76 }
2:POJ 3254
Corn Fields
入门提: 1 #include<stdio.h>
2 #include<string.h>
3 #include<math.h>
4 #include<vector>
5 #include<algorithm>
6 using namespace std;
7 int dp[22][1<<13];
8 int mp[20][20];
9 vector<int> v[2134];
10 const int M=100000000;
11 int n,m;
12 int t;
13 int state[123456];
14
15 void init()
16 {
17 t=0;
18 for (int i=0;i<n;i++)
19 for (int j=0;j<m;j++) scanf("%d",&mp[i][j]);
20 for (int i=0;i<(1<<m);i++)
21 {
22 if (i&(i>>1)) continue;
23 if (i&(i<<1)) continue;
24 state[++t]=i;
25 }
26 for (int i=0;i<n;i++)
27 {
28 v[i].clear();
29 for (int j=1;j<=t;j++){
30 int flag=1;
31 for (int p=0;p<m;p++)
32 if (mp[i][p]==0&&(state[j]&(1<<p)))
33 {
34 flag=0;
35 break;
36 }
37 if (flag) v[i].push_back(state[j]);
38 }
39 }
40 }
41
42 int main()
43 {
44 while (scanf("%d%d",&n,&m)!=EOF)
45 {
46 init();
47 memset(dp,0,sizeof(dp));
48 for (int i=0;i<v[0].size();i++) dp[0][i]=1;
49 for (int i=1;i<n;i++)
50 for (int j=0;j<v[i].size();j++){
51 int now=v[i][j];
52 for (int k=0;k<v[i-1].size();k++)
53 if (!(now&(v[i-1][k])))
54 {dp[i][j]+=dp[i-1][k];
55 dp[i][j]%=M;
56 }
57 }
58 int ans=0;
59 for (int i=0;i<v[n-1].size();i++){
60 ans+=dp[n-1][i];
61 ans%=M;
62 }
63 printf("%d\n",ans);
64 }
65 return 0;
66 }
3 #include<math.h>
4 #include<vector>
5 #include<algorithm>
6 using namespace std;
7 int dp[22][1<<13];
8 int mp[20][20];
9 vector<int> v[2134];
10 const int M=100000000;
11 int n,m;
12 int t;
13 int state[123456];
14
15 void init()
16 {
17 t=0;
18 for (int i=0;i<n;i++)
19 for (int j=0;j<m;j++) scanf("%d",&mp[i][j]);
20 for (int i=0;i<(1<<m);i++)
21 {
22 if (i&(i>>1)) continue;
23 if (i&(i<<1)) continue;
24 state[++t]=i;
25 }
26 for (int i=0;i<n;i++)
27 {
28 v[i].clear();
29 for (int j=1;j<=t;j++){
30 int flag=1;
31 for (int p=0;p<m;p++)
32 if (mp[i][p]==0&&(state[j]&(1<<p)))
33 {
34 flag=0;
35 break;
36 }
37 if (flag) v[i].push_back(state[j]);
38 }
39 }
40 }
41
42 int main()
43 {
44 while (scanf("%d%d",&n,&m)!=EOF)
45 {
46 init();
47 memset(dp,0,sizeof(dp));
48 for (int i=0;i<v[0].size();i++) dp[0][i]=1;
49 for (int i=1;i<n;i++)
50 for (int j=0;j<v[i].size();j++){
51 int now=v[i][j];
52 for (int k=0;k<v[i-1].size();k++)
53 if (!(now&(v[i-1][k])))
54 {dp[i][j]+=dp[i-1][k];
55 dp[i][j]%=M;
56 }
57 }
58 int ans=0;
59 for (int i=0;i<v[n-1].size();i++){
60 ans+=dp[n-1][i];
61 ans%=M;
62 }
63 printf("%d\n",ans);
64 }
65 return 0;
66 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。