• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
AC_Artist.zig_zag
然而我依然在补题、
博客园    首页    新随笔    联系   管理    订阅  订阅

bzoj 2004[Hnoi2010]Bus 公交线路

状压DP。

f[i][s]表示第i个车站之前的p位的状态为s的方案数,注意这里状态s我们规定第一位为1,并且一共有k个1。

这样的话状态一共有C(9,4)=126种,于是设计一个126*126的矩阵,自乘n-m次就可以了;

初始状态:11111(m个1)的状态;

目标状态:11111(m个1)的状态。

bus
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #define maxn 1200
 7 #define inf 2147483647
 8 #define ms 30031
 9 using namespace std;
10 int st[maxn],v[maxn];
11 int n,m,p,num,ans;
12 struct mat
13 {
14     int m[200][200];
15     void clean()
16     {
17         for (int i=1;i<=num;i++)
18             for (int j=1;j<=num;j++)
19                 m[i][j]=0;
20     }
21     friend mat operator *(const mat &a,const mat &b)
22     {
23         mat c;
24         c.clean();
25         for (int i=1;i<=num;i++)
26             for (int j=1;j<=num;j++)
27             {
28                 for (int k=1;k<=num;k++)
29                     c.m[i][j]=c.m[i][j]+(a.m[i][k]*b.m[k][j])%ms;
30                 c.m[i][j]=c.m[i][j]%ms;
31             }
32         return c;
33     }
34 }T,E;
35 
36 bool  judge(int x)
37 {
38     if (x%2==0) return 0;
39     int cnt=0;
40     for (int i=1;i<=p;i++)
41     {
42         if (x&1) cnt++;
43         x=x/2;
44     }
45     if (cnt!=m) return 0;
46     else return 1;
47 }
48 
49 void debug(mat *a)
50 {
51     for (int i=1;i<=num;i++)
52     {
53         for (int j=1;j<=num;j++)
54             cout<<a->m[i][j]<<' ';
55         cout<<endl;
56     }
57 }
58 
59 int main()
60 {
61     scanf("%d%d%d",&n,&m,&p);
62     for (int i=1;i<=((1<<p)-1);i++)
63         if (judge(i)) st[++num]=i,v[i]=num;
64     for (int i=1;i<=num;i++)
65     {
66         int x=st[i];
67         int y=x/2;
68         for (int j=1;j<=p;j++)
69             if (v[y|(1<<(j-1))]) T.m[i][v[y|(1<<(j-1))]]=1;
70     }
71     //debug(&T);
72     E.m[1][v[(1<<m)-1]]=1;
73     int tmp=n-m;
74     while (tmp)
75     {
76         if (tmp&1) E=E*T;
77         tmp=tmp>>1;
78         T=T*T;
79     }
80     ans=E.m[1][v[(1<<m)-1]];
81     printf("%d\n",ans);
82     return 0;
83 }

 

AC without art, no better than WA !
posted @ 2013-05-03 09:47  Zig_zag  阅读(362)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3