您的位置:首页 > 编程语言 > Go语言

Dyslexic Gollum

2015-10-25 21:09 260 查看
题意:

求长度是n的二进制串中,不含长度大于等于k的回文串的个数

分析:

dp[i][j][k]表示长度i,后11位状态是j不含长度大于等于k的回文串的个数(因为k最大是10,所把后11位状态压缩,dp[i][j][k]=dp[i-1][j>>1][k]+dp[i-1][j>>1|(1<<10)][k],i-1的低11位就是i的高11位以此转移过来)

预处理出来[1,1<<11)中的最大回文串长度,方便统计。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <complex>
#include <cassert>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
#define lson l,m,rt<<1
#define pi acos(-1.0)
#define rson m+1,r,rt<<11
#define All 1,N,1
#define read freopen("in.txt", "r", stdin)
const ll  INFll = 0x3f3f3f3f3f3f3f3fLL;
const int INF= 0x7ffffff;
const int mod =  1000000007;
int num[410][15],b[15][1<<11],dp[410][1<<11][15];
int pos[15];
void init(){
b[1][0]=b[1][1]=1;
for(int i=2;i<=11;++i){
int cas=(1<<i);
for(int j=0;j<cas;++j){
int q=j;
for(int k=1;k<=i;++k)
{
pos[k]=q%2;
q/=2;
}
int f=1;
for(int k=1;k<=i/2;++k)
if(pos[k]!=pos[i-k+1]){
f=0;
break;
}
if(f)
b[i][j]=i;
else{
b[i][j]=max(b[i-1][j&((1<<(i-1))-1)],b[i-1][j>>1]);
}

}
}
for(int i=1;i<=11;++i)
{
int cas=(1<<i);
for(int j=0;j<cas;++j)
for(int k=b[i][j]+1;k<=10;++k)
{
if(i==11)dp[11][j][k]++;
num[i][k]++;
}
}
for(int i=12;i<=400;++i){
for(int j=0;j<(1<<11);++j)
for(int k=2;k<=10;++k)
{
if(b[11][j]>=k)
dp[i][j][k]=0;
else{
dp[i][j][k]=(dp[i-1][j>>1][k]+dp[i-1][(j>>1)|(1<<10)][k])%mod;
num[i][k]=(num[i][k]+dp[i][j][k])%mod;
}
}
}
}
int main()
{
init();
int t,n,m;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
printf("%d\n",num
[m]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: