POJ 3254 Corn Fields(状态压缩dp)
2016-08-22 09:31
417 查看
题目分析
状态压缩通常用来处理那些状态很多导致不能容易表达出来,于是需要通过压缩状态进行表示,又利用比如位运算处理一些东西,很容易将结果求出来。我的第一道状态压缩题,注释写的很详细。#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int MOD = 100000000; int M,N,top = 0; int state[600],num[110]; int dp[20][600]; int cur[20]; inline bool ok(int x){ //判断是否有相邻1 if(x&x<<1) return 0; return 1; } void init(){ //将所有能放的状态全部存储进来 top = 0; int total = 1<<N; for(int i = 0; i < total; ++i) if(ok(i)) state[++top] = i; } inline bool fit(int x,int k){ //判断是否与当前状态冲突 if(x&cur[k]) return 0; return 1; } int main(){ while(scanf("%d%d", &M, &N) != EOF){ init(); memset(dp, 0, sizeof(dp)); for(int i = 1; i <= M; i++){ cur[i] = 0; int num; for(int j = 1; j <= N; j++){ scanf("%d", &num); if(num == 0) cur[i] += (1<<(N-j)); //cur中存放不能放的位置 } } for(int i = 1; i <= top; i++) //将第一行能放的状态找出来 if(fit(state[i], 1)) dp[1][i] = 1; for(int i = 2; i <= M; i++){ for(int k = 1; k <= top; ++k){ if(!fit(state[k], i)) continue; //当前放的位置与cur冲突 for(int j = 1; j <= top; j++){ if(!fit(state[j], i-1)) continue; //判断上一行的这个位置能否放 if(state[k]&state[j]) continue; //判断当前行与上一行是否冲突 dp[i][k] = (dp[i][k] + dp[i-1][j])%MOD; } } } int ans = 0; for(int i = 1; i <= top; i++) ans = (ans+dp[M][i])%MOD; printf("%d\n", ans); } return 0; }
相关文章推荐
- POJ 3254 Corn Fields(状态压缩DP)
- POJ 3254 Corn Fields(DP + 状态压缩)
- POJ 3254 Corn Fields (状态压缩DP)
- poj 3254 Corn Fields (状态压缩dp)
- POJ 3254 Corn Fields (状态压缩DP)
- POJ-3254 Corn Fields 入门级状态压缩DP
- poj 3254 Corn Fields (状态压缩dp)
- 状态压缩DP-Corn Fields(POJ 3254)
- POJ 3254 Corn Fields状态压缩DP
- POJ 3254 Corn Fields 状态压缩DP
- POJ-3254 Corn Fields 状态压缩DP+滚动数组
- POJ 3254 Corn Fields(状态压缩DP)
- poj 3254 Corn Fields (状态压缩DP)
- POJ 3254 Corn Fields 状态压缩dp
- poj 3254 Corn Fields(状态压缩dp)
- poj-3254-Corn Fields-状态压缩DP
- POJ 3254 Corn Fields 状态压缩DP
- Poj - 3254 Corn Fields (状态压缩dp入门第一题(详解
- POJ 3254 Corn Fields (状态压缩DP)
- POJ3254——Corn Fields(状态压缩DP)