【题目分析】

    沉迷水题,吃枣药丸。

    BZOJ 1087 [SCOI2005]互不侵犯King ——状压DP

【代码】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define ll long long
int cot[512],c1[512],c2[512][512],n,p;
ll dp[10][512][90];
void print(int x)
{
    F(i,0,n-1) printf("%d",(x>>i)&1);
}
void init()
{
    F(i,0,(1<<n)-1)
    {
        int x=i,ret=0;
        while (x) ret+=x&1,x>>=1;
        cot[i]=ret;
    }
    F(i,0,(1<<n)-1)
        if ((!((i>>1)&i))&&(!((i<<1)&i))) c1[i]=1;
    F(i,0,(1<<n)-1) if (c1[i])
    F(j,0,(1<<n)-1) if (c1[j])
    if ((!((j>>1)&i))&&(!((j<<1)&i))&&(!(j&i)))
        {
//          print(i); printf("---> "); print(j); printf("\n");
            c2[i][j]=1;
        }
}
int main()
{
    scanf("%d%d",&n,&p);
    init();
    F(i,0,(1<<n)-1) if (c1[i]) dp[1][i][cot[i]]=1;
    F(i,1,n-1) F(j,0,(1<<n)-1)
    F(k,0,p)   F(l,0,(1<<n)-1)
        if (c2[j][l])
        {
//          printf("dp[%d] ",i+1); print(l); printf(" %d += dp[%d] ",k+cot[l],i); print(j); printf(" %d  = %d\n",k,dp[i][j][k]);
            dp[i+1][l][k+cot[l]]+=dp[i][j][k];
        }
    ll ans=0;
    F(i,0,(1<<n)-1) ans+=dp[n][i][p];
    printf("%lld\n",ans);
}

  

相关文章:

  • 2021-10-11
  • 2021-06-30
  • 2021-05-23
  • 2021-09-17
  • 2021-07-27
  • 2021-05-22
  • 2022-01-02
猜你喜欢
  • 2021-10-26
  • 2021-10-06
  • 2021-10-12
  • 2022-12-23
  • 2021-08-14
  • 2022-03-07
  • 2022-02-04
相关资源
相似解决方案