这几天就顾着看以前的题,不写的码手还是会生疏啊

状态压缩+矩阵乘法

发现在长度为P的区间中符合题意的很有限,所以先压缩完建出图,用矩阵加速转移

为什么有状态压缩大家都要弄个DP上去呢,感觉只有压缩的部分没有DP呀。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<queue>
 5 #include<iostream>
 6 #define inc(i,l,r) for(int i=l;i<=r;i++)
 7 #define dec(i,l,r) for(int i=l;i>=r;i--)
 8 #define mem(a) memset(a,0,sizeof(a))
 9 #define inf 30031
10 #define ll long long
11 #define succ(x) (1<<x)
12 #define lowbit(x) (x&(-x))
13 #define NM 200
14 using namespace std;
15 int read(){
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
18     while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
19     return x*f;
20 }
21 int c[NM],n,m,p,cnt,ans;
22 struct mat{
23     int a[NM][NM];
24 }s,t;
25 mat operator*(const mat&x,const mat&y){
26     mat s;mem(s.a);
27     inc(i,1,cnt)inc(j,1,cnt)inc(k,1,cnt)
28     (s.a[i][j]+=x.a[i][k]*y.a[k][j])%=inf;
29     return s;
30 }
31 void dfs(int x,int t,int num){
32     if(x==p){
33         if(num==m)c[++cnt]=t;return;
34     }
35     dfs(x+1,t<<1,num);dfs(x+1,t<<1|1,num+1);
36 }
37 void out(mat t){
38     inc(i,1,cnt){
39         inc(j,1,cnt)printf("%d ",t.a[i][j]);putchar('\n');
40     }putchar('\n');
41 }
42 int main(){
43     freopen("data.in","r",stdin);
44     n=read();m=read();p=read();
45     dfs(1,1,1);
46     inc(i,1,cnt)inc(j,1,cnt){
47         int x=(c[i]<<1)^succ(p)^c[j];
48         if(x==lowbit(x))t.a[i][j]=1;
49     }
50 //    out(t);
51     inc(i,1,cnt)s.a[i][i]=1;
52     p=n-m;
53     for(mat V=t;p;p>>=1,V=V*V)
54     if(p&1)s=s*V;
55 //    out(s);
56     printf("%d\n",s.a[cnt][cnt]);
57     return 0;
58 }
View Code

 

posted on 2016-03-25 21:37  onlyRP  阅读(205)  评论(0编辑  收藏  举报