• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
DementRock
   首页          管理     

Sgu 223

此题可用状态压缩来做,首先dfs出单独一行所有可能的放置状态,存入数组s(如n=3时s[1]=000,s[2]=100,s[3]=010,s[4]=001,s[5]=101),并设c[t]为s[t]中1的个数。
设f[l][t][k]是前l行已放完,第l行状态为s[t]且前l行共放置k个棋子的方法数,则

f[l][t][k]=Sum{f[l-1][i][k-c[k]]},其中s[i]和s[t]需满足:s[i] and s[t]=0,且(s[i]*2) and s[t]=0,且(s[i]/2) and s[t]=0,边界条件为f[0][1][0]=1,f[0][i][j]=0(i!=1||j!=0)。

最后答案为Sum{f[n][i][k]}

考虑到本题的数据范围,f数组需用long long类型存储。

sgu223
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 int s[145],c[145],m,n,k;
 5 long long f[11][145][101];
 6 void dfs(int l, int now, int total)
 7 {
 8     if(l==n)
 9     {
10         s[++m]=now;
11         c[m]=total;
12         return;
13     }
14     dfs(l+1,now<<1,total);
15     if(!(now&1))
16         dfs(l+1,(now<<1)|1,total+1);
17 }
18 void dp(int l, int t, int k)
19 {
20     f[l][t][k]=0;
21     for(int i=1;i<=m;++i)
22         if(k>=c[t]&&!(s[i]&s[t])&&!((s[i]>>1)&s[t])&&!((s[i]<<1)&s[t]))
23         {
24             if(f[l-1][i][k-c[t]]==-1)
25                 dp(l-1,i,k-c[t]);
26             f[l][t][k]+=f[l-1][i][k-c[t]];
27         }
28 }
29 int main()
30 {
31     long long ans=0;
32     scanf("%d%d",&n,&k);
33     memset(f,0xff,sizeof(f));
34     dfs(0,0,0);
35     memset(f[0],0,sizeof(f[0]));
36     f[0][1][0]=1;
37     for(int i=1;i<=m;++i)
38     {
39         if(f[n][i][k]==-1)
40             dp(n,i,k);
41         ans+=f[n][i][k];
42     }
43     printf("%I64d\n",ans);
44     return 0;
45 }


posted @ 2010-02-16 18:39  DementRock  阅读(401)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3