您的位置:首页 > 其它

poj 3254 Corn Fields(他们说是状压dp??)

2017-08-21 20:49 477 查看
这题是状压dp,他们还说是最简单的?

好像确实不难,但我真的想了好久.

好菜啊好菜啊

讲实话,这题我不知道跟dp有什么关系,唯一的地方也就是在这里巧妙的运用了很多位运算.

嗯,然后我用了很妖的方法来解决,还手打了一组数据,发现网上一个题解居然会给出负数解(就是百度第一个),真的很搞笑.

我要去看看他们怎么说的了.

/*  xzppp  */
#include <iostream>
#include <vector>
#include <cstdio>
#include <string.h>
using namespace std;
#define FFF freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#define lson MAXN,m,rt<<1
#define rson m+1,r,rt<<1|1
#define MP make_pair
#define PB push_back
typedef long long  LL;
typedef unsigned long long ULL;
const int MAXN = 1e6+17;
const int MAXM = 20;
const int INF = 0x7fffffff;
const int MOD = 100000000;
int a[12+17][12+17];
int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
FFF
#endif
int n,m;
cin>>n>>m;
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
scanf("%d",&a[i][j]);
vector<pair<int,int > > last;
last.PB(MP(0,1));
LL ans = 1;
for (int i = 0; i < n; ++i)
{
int dis = 0;
vector<pair<int,int > > now;
now.clear();
for (int j = 0; j < 1<<m; ++j)
{
int can = true;
if((j<<1&j)!=0)
can = false;
for (int k = m-1,x = 0; can&&k > -1; --k,++x)
{
if(a[i][k]==0&&j>>x&1)
{
can =false;
break;
}
}
if(can)
for (int k = 0; k < last.size(); ++k)
{
int dis = 0;
if((last[k].first&j)==0)
{
if(j==0) dis+=last[k].second;
if(!now.empty())
{
if(now[now.size()-1].first==j)
now[now.size()-1].second+=last[k].second;
else
now.PB(MP(j,last[k].second));
}
else
now.PB(MP(j,last[k]).second);
ans = (ans + last[k].second-dis)%MOD;
}
}
}
last.clear();
for (int i = 0; i < now.size(); ++i)
last.PB(now[i]);
}
cout<<ans%MOD<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj 位运算