UVA 1633-Dyslexic Gollum 状态压缩DP
2017-08-18 20:23
281 查看
题意 :
输入n和k 求出长度为n的01串中有多少个不含长度至少为K的回文连续子串。
思路:
没有思路 看题解照着敲的。。。
首先 长的回文串由短的回文串构成,那么我们只需要避免构造的字符串出现长度为k和k+1的回文字符串就好了。
题目说的是01串 回文串长度最大是10 那么肯定是要用到状压DP的。
定义 dp[i][j] 表示长度为i的字符串后k位的二进制表示为j的合法字符串有多少个
分情况进行转移 i < k时
k<=i时 我们就有些麻烦了 我们要考虑j表示的串是否是回文串 j后面填上0或1后是否是回文串 每次都单独判断的话很耗时间 我们可以预处理一下
全部代码如下
输入n和k 求出长度为n的01串中有多少个不含长度至少为K的回文连续子串。
思路:
没有思路 看题解照着敲的。。。
首先 长的回文串由短的回文串构成,那么我们只需要避免构造的字符串出现长度为k和k+1的回文字符串就好了。
题目说的是01串 回文串长度最大是10 那么肯定是要用到状压DP的。
定义 dp[i][j] 表示长度为i的字符串后k位的二进制表示为j的合法字符串有多少个
分情况进行转移 i < k时
if(i<k) { judge[i+1][j<<1]=(judge[i+1][j<<1]+judge[i][j])%MOD; judge[i+1][j<<1|1]=(judge[i+1][j<<1|1]+judge[i][j])%MOD; }
k<=i时 我们就有些麻烦了 我们要考虑j表示的串是否是回文串 j后面填上0或1后是否是回文串 每次都单独判断的话很耗时间 我们可以预处理一下
void init() { memset(dp,-1,sizeof dp); dp[1][1]=0; dp[1][0]=0; dp[2][0]=dp[2][3]=0; for(int i=1; i<=11; i++) { int top=1<<i; for(int j=0; j<top; j++) { if(dp[i][j]==0) { dp[i+2][j<<1]=0; dp[i+2][fills(j,1,i)]=0; } } } } // dp else { if(dp[k][j]==0) continue; int statu=j<<1; if(dp[k+1][statu]!=0)// 末尾填0 { int cnt=statu; if(cnt>=(1<<k)) cnt-=(1<<k); if(dp[k][cnt]!=0) judge[i+1][cnt]=(judge[i+1][cnt]+judge[i][j])%MOD; } if(dp[k+1][statu|1]!=0) { int cnt=statu|1; if(cnt>=(1<<k)) cnt-=(1<<k); if(dp[k][cnt]!=0) judge[i+1][cnt]=(judge[i+1][cnt]+judge[i][j])%MOD; } }
全部代码如下
# include<iostream>
# include<cstdio>
# include<cstring>
# include<algorithm>
using namespace std;
const int MOD=1e9+7;
int judge[405][1<<12];// dp[i][j][k] 表示 前i位数 长度为j的后缀二进制表示为k的合法串有多少种
int dp[15][1<<12];// 判断数组 二进制状态表示为j 长度为i的串是否为回文子串
int fills(int j,int dig,int len)
{
if(dig)
{
return ((j<<1)+1)|(1<<(len+1));
}
else return j<<1;
}
void init()
{
memset(dp,-1,sizeof dp);
dp[1][1]=0;
dp[1][0]=0;
dp[2][0]=dp[2][3]=0;
for(int i=1; i<=11; i++)
{
int top=1<<i;
for(int j=0; j<top; j++)
{
if(dp[i][j]==0)
{
dp[i+2][j<<1]=0;
dp[i+2][fills(j,1,i)]=0;
}
}
}
}
char str[100];
int main()
{
init();
int T;
cin>>T;
while(T--)
{
int n,k;
scanf("%d %d",&n,&k);
memset(judge,0,sizeof judge);
int ans=0;
judge[1][0]=judge[1][1]=1;
for(int i=1;i<=n;i++)
{
int top=1<<min(i,k);
for(int j=0;j<top;j++)
{
//printf("judge[%d][%d]=%d\n",i,j,judge[i][j]);
if(i<k) { judge[i+1][j<<1]=(judge[i+1][j<<1]+judge[i][j])%MOD; judge[i+1][j<<1|1]=(judge[i+1][j<<1|1]+judge[i][j])%MOD; }
else
{
if(dp[k][j]==0)
continue;
int statu=j<<1;
if(dp[k+1][statu]!=0)// 末尾填0
{
int cnt=statu;
if(cnt>=(1<<k))
cnt-=(1<<k);
if(dp[k][cnt]!=0)
judge[i+1][cnt]=(judge[i+1][cnt]+judge[i][j])%MOD;
}
if(dp[k+1][statu|1]!=0)
{
int cnt=statu|1;
if(cnt>=(1<<k))
cnt-=(1<<k);
if(dp[k][cnt]!=0)
judge[i+1][cnt]=(judge[i+1][cnt]+judge[i][j])%MOD;
}
}
if(i==n)
ans=(judge[i][j]+ans)%MOD;
}
}
cout<<ans<<endl;
}
}
相关文章推荐
- UVA 1633-Dyslexic Gollum(状态压缩DP)
- 100道动态规划——24 UVA 1633 Dyslexic Gollum 状态压缩DP 挺好的题 因为窝没想到嘛
- Uva-1633 Dyslexic Gollum(状压DP)
- uva 11795 Mega Man's Mission(动态规划-状态压缩DP)
- uva 10651 Pebble Solitaire(dp,状态压缩,记忆化搜索)
- uva 10817 - Headmaster's Headache ( 状态压缩dp)
- UVALive 6625 Diagrams & Tableaux (状态压缩DP)
- Uva 10817 - Headmaster's Headache(状态压缩DP)
- UVA 11825 Hackers' Crackdown DP+状态压缩 -
- uva_11008 - Antimatter Ray Clearcutting ( 状态压缩DP )
- uva 11795 Mega Man's Mission(动态规划-状态压缩DP)
- UVA 10911 Forming Quiz Teams(状态压缩DP)
- UVA 11825 - Hackers' Crackdown(状态压缩DP)
- UVA 6625(状态压缩dp)
- uva 10651 状态压缩DP
- 【Uva 1633】Dyslexic Gollum
- UVA - 11795 Mega Man's Mission 状态压缩DP
- Uva 10817 Headmaster's Headache (DP+ 状态压缩)
- uva_10651_Pebble Solitaire(状态压缩DP)
- UVA 1252-Twenty Questions(状态压缩DP+子集枚举)