POJ 3254 简单状压DP

没什么可说的,入门级状压DP,直接撸掉

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <set>
#define LL long long
#define FOR(i, x, y) for(int i=x;i<=y;i++)
using namespace std;
const int maxn = 5000;
const int MOD = 100000000;
int N, M, K;
int C[20], state[maxn];
int dp[20][maxn];
bool judge(int x)
{
    if(x & (x << 1)) return false;
    return true;
}
void init()
{
    memset(dp, 0, sizeof(dp));
    memset(state, 0, sizeof(state));
    memset(C, 0, sizeof(C));
    int r = (1 << M) - 1; K = 0;
    FOR(i, 0, r) if(judge(i)) state[++K] = i;
}
int main()
{
    while(scanf("%d %d", &N, &M)!=EOF)
    {
        init();
        int X;
        FOR(i, 1, N)
        FOR(j, 1, M)
        {
            scanf("%d", &X);
            if(X == 0) C[i] = C[i] | (1 << (M - j));
        }
        FOR(i, 1, K)
        {
            if(!(state[i] & C[1])) dp[1][i] = 1;
        }

        FOR(i, 2, N)
        FOR(j, 1, K)
        {
            if(C[i-1] & state[j]) continue;
            FOR(l, 1, K)
            {
                if((C[i] & state[l]) || (state[l] & state[j])) continue;
                dp[i][l] = (dp[i-1][j] + dp[i][l]) % MOD;
            }
        }
        int ans = 0;
        FOR(i, 1, K) ans = (ans + dp[N][i]) % MOD;
        printf("%d\n", ans);
    }
    return 0;
}
时间: 2024-08-24 14:41:38

POJ 3254 简单状压DP的相关文章

POJ 2688 BFS+状压DP

标准的TSP问题 m*n矩阵,有不超过10个需要走到的点,给出起点,问走最少的步子把所有点走完 BFS出每个必须走到的点的最短距离 然后状压DP即可 #include "stdio.h" #include "string.h" #include "queue" using namespace std; const int dir[4][2]={ {1,0},{-1,0},{0,1},{0,-1} }; int inf=0x7fffffff; in

Hie with the Pie(POJ 3311)状压DP

Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possible. Unfortunately, due to cutbacks, they can afford to hire only one driver to do the deliveries. He will wait for 1 or more (up to 10) orders to be

poj 1185 (状压dp)

Problem 炮兵阵地 题目大意 给你一张n*m的地图,一些地区是空地,一些地区是障碍. 可以在空地上布置炮兵部队,炮兵部队的攻击范围为上下左右各两格. 询问最多可以布置多少个炮兵部队,且互不伤害. 0<=N <= 100 , 0<=M <= 10 解题分析 由于攻击范围是两格,所以用dp[i][j][k]表示做到i行,上一行的状态为j,上上行的状态为k. 判断上下两行的状态i,j是否矛盾,直接判断 i&j 是否为0即可. 判断同一行的状态i是否矛盾,用 i &

POJ 1185 经典状压dp

做了很久的题 有注释 #include<stdio.h> #include<string.h> #include<algorithm> #include<map> #include<math.h> using namespace std; int dp[107][107][107];///二维记录上一次 三维记录此次 ///dp[i][k][j]=max(dp[i][k][j],dp[i-1][t][k])+num[j]; t为枚举数且满足与 k

NYOJ832 合并游戏(简单状压DP)

AC代码: #include<stdio.h> #include<string.h> #define max(a,b) (((a)>(b))?(a):(b)) int dp[10000],a[12][12],n; int dj(int x){ int i,j,temp,Mx=0,mx; if(dp[x]!=-1) return dp[x]; //搜过的状态要标记, 这要注意!! 不写的话会超时 if(x==0) return 0; for(i=0;i<n;i++){ m

ch0103 位运算,简单状压dp

题意:n个顶点带权无向图,求最短hamilton路径长度(从起点0走到终点n-1,且经过每个顶点恰好一次的路径) 在看位运算的时候做到这题,觉得状态压缩的思路挺奇特的.本来n<20,O(n!*n)的算法肯定炸了,但是可以二进制表示状态 如果将i表示为二进制,i的第j位走过就为1,没走过就为0(注意二进制位从0~n-1),此处1<=i<2^n-1 用dp[i][j]表示状态i,到达第j个城市的最小值,那么i的二进制第j位为1(到达第j个城市),且i的二进制第j位取反之后,二进制第k位为1(

[Usaco2008 Nov]mixup2 混乱的奶牛 简单状压DP

1231: [Usaco2008 Nov]mixup2 混乱的奶牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 685  Solved: 383[Submit][Status][Discuss] Description 混乱的奶牛 [Don Piele, 2007] Farmer John的N(4 <= N <= 16)头奶牛中的每一头都有一个唯一的编号S_i (1 <= S_i <= 25,000). 奶牛为她们的编号感到骄傲,

UVA 1252 Twenty Questions 状压DP

简单状压DP: 当前状态s如果这个物品有状态a个属性,枚举下一个要猜测的特征k dp[s][a]=min(dp[s][a],max(dp[s+k][a],dp[s+k][a+k])+1); 4643 - Twenty Questions Asia - Tokyo - 2009/2010 Consider a closed world and a set of features that are defined for all the objects in the world. Each feat

状压DP [ZOJ 3471] Most Powerful

Most Powerful Time Limit: 2 Seconds      Memory Limit: 65536 KB Recently, researchers on Mars have discovered N powerful atoms. All of them are different. These atoms have some properties. When two of these atoms collide, one of them disappears and a