题解 P2435 【染色】
RainFestival · · 题解
这道题一看就是其实是一个dp,轮廓线dp
设点i,j上一个轮廓线为u
那么如果u的第m位与第0位(二进制从低到高,第k位价值2^k)
都不与当前要填的数不同,就可以进行状态转移
我们再用滚动数组优化空间即可
附上带有简单优化常数的我不优化有一个点过不去代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#define mod 376544743
using namespace std;
long long dp[5][300000],a[15],ans,sp1[100005],sp2[100005];
int n,m,kk,now,maxs,s1,s2,can,bo;
inline void update(register int x1,register int x2,register int x,register int y)
{
dp[now][x2]=(dp[now][x2]+dp[now^1][x1])%mod;
}
inline void put(register int x,register int y,register int can)
{
if (y/a[m-1]!=x&&(y%kk!=x||can)) update(y,(y*kk+x)%a[m],x,y);
}
inline int check(int x,int y)
{
while (x>0||y>0)
{
if (x%kk==y%kk) return 0;
x=x/kk,y=y/kk;
}
return 1;
}
int main()
{
srand(time(NULL));
scanf("%d%d%d",&n,&m,&kk);
if (kk==2)
{
//printf("%d",rand()%2);
//return 0;
bo=1;
for (register int i=1;i<=m;++i)
{
//scanf("%d",&sp1[i]);
char ch=getchar();
while (ch!='0'&&ch!='1') ch=getchar();
sp1[i]=ch-48;
if (sp1[i]==sp1[i-1]) bo=0;
}
for (register int i=1;i<=m;++i)
{
//scanf("%d",&sp2[i]);
char ch=getchar();
while (ch!='0'&&ch!='1') ch=getchar();
sp2[i]=ch-48;
if (sp2[i]==sp2[i-1]) bo=0;
}
for (int i=1;i<=m;++i)
if ((sp1[i]+n)%2==sp2[i]) bo=0;
printf("%d\n",bo);
return 0;
}
a[0]=1;
maxs=1;
for (int i=1;i<=m-1;++i)
a[i]=a[i-1]*kk;
a[m]=a[m-1]*kk;
maxs=a[m]-1;
for (int i=1;i<=m;++i)
{
int x,y=-1;
scanf("%d",&x);
if (i!=1&&x==y)
{
printf("%d\n",0);
return 0;
}
s1=s1*kk+x;
y=x;
}
for (int i=1;i<=m;++i)
{
int x,y=-1;
scanf("%d",&x);
if (i!=1&&x==y)
{
printf("%d\n",0);
return 0;
}
s2=s2*kk+x;
y=x;
}
dp[0][s1]=1;
now=0;
for (register int i=1;i<n;++i)
for (register int j=1;j<=m;++j)
{
if (i==1&&j!=m) continue;
if (i==n-1&&j==m) break;
if (j==m) can=1;
else can=0;
now=now^1;
for (register int k=0;k<=maxs;++k) dp[now][k]=0;
for (register int k=0;k<=maxs;++k)
{
if (dp[now^1][k]==0) continue;//去掉对答案无贡献的状态,节约时间
for (register int p=0;p<kk;++p)
put(p,k,can);
}
}
for (register int i=0;i<=maxs;++i)
if (check(i,s2)) ans=(ans+dp[now][i])%mod;
printf("%lld\n",ans);
return 0;
}
然后就accepted了
时间808ms,内存3860KB,代码长度4.08KB
感谢大佬们的观赏