标签:c++ ++ cas \n ret using += vector 需要
题意:有障碍物的多回路的插头dp,求方案数
题解:其实搞懂插头dp的插头方式就和轮廓线dp一样了,因为这题是多回路,不需要单回路的连通性;‘
dp[i][j]表示第i行j状态的方案数
需要注意的是第二维我们维护了m+1个状态,因为对于插头可能会有m+1种情况,对于每一个位置有插头就是1,否则就是0
一共有四种情况:
假设当前位置是障碍物,那么只有没有上插头和左插头的情况能够转移到没有上左插头的情况
假设当前位置不是障碍物,那么
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)
using namespace std;
const double g=10.0,eps=1e-12;
const int N=(1ll<<12)+10,maxn=1000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
ll dp[2][N];
int n,m,a[12][12];
ll solve()
{
memset(dp,0,sizeof dp);
int now=0,pre=1;
dp[now][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
swap(now,pre);
memset(dp[now],0,sizeof dp[now]);
if(a[i][j]==0)
{
for(int k=0;k<(1<<(m+1));k++)
if((!((k>>m)&1)) && (!(k&1)))
dp[now][k<<1]+=dp[pre][k];
continue;
}
for(int k=0;k<(1<<(m+1));k++)
{
if(((k>>m)&1) && (!(k&1)))
{
if(j!=m)dp[now][((k^(1<<m))<<1)|1]+=dp[pre][k];
if(i!=n)dp[now][((k^(1<<m))<<1)|2]+=dp[pre][k];
}
else if((!((k>>m)&1)) && (k&1))
{
if(i!=n)dp[now][k<<1]+=dp[pre][k];
if(j!=m)dp[now][(k<<1)^3]+=dp[pre][k];
}
else if((!((k>>m)&1)) && (!(k&1)))
{
if(j!=m&&i!=n)dp[now][(k<<1)|3]+=dp[pre][k];
}
else
{
dp[now][((k^(1<<m))<<1)^2]+=dp[pre][k];
}
}
}
}
return dp[now][0];
}
int main()
{
int T;scanf("%d",&T);
for(int _=1;_<=T;_++)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
printf("Case %d: There are %lld ways to eat the trees.\n",_,solve());
}
return 0;
}
/***********************
***********************/
标签:c++ ++ cas \n ret using += vector 需要
原文地址:https://www.cnblogs.com/acjiumeng/p/9095461.html