【SCOI 2005】 互不侵犯

【题目链接】

           点击打开链接

【算法】

         和HDU2167类似

         先搜出一行内符合的状态,然后,f[i][j][k]表示第i行,第j种状态,放了k个,合法的方案,DP即可

【代码】

         

#include<bits/stdc++.h>
using namespace std;
#define MAXN 10
#define MAXK 85
const int MAXS = 1024;

int i,j,x,y,tot,n,k,tmp,MASK;
long long f[MAXN][MAXS][MAXK];
long long ans;

struct info 
{
        int x,s;
} ST[MAXS];

int calc(int s)
{
        int i,ret = 0;
        for (i = 0; i < n; i++)
        {
                if (s & (1 << i))
                        ret++;
        }
        return ret;    
}

int main()
{
    
        scanf("%d%d",&n,&k);
        MASK = (1 << n) - 1;
        for (i = 0; i <= MASK; i++)
        {
                if (i & (i << 1)) continue;
                tmp = calc(i);
                if (tmp <= k) ST[++tot] = (info){i,tmp};
                f[1][tot][tmp] = 1;
        }    
        for (i = 2; i <= n; i++)
        {
                for (j = 1; j <= tot; j++)
                {
                        for (x = ST[j].s; x <= k; x++)
                        {
                            for (y = 1; y <= tot; y++)
                            {
                                    if (ST[j].x & ST[y].x) continue;
                                    if (ST[j].x & (ST[y].x << 1)) continue;
                                    if (ST[j].x & (ST[y].x >> 1)) continue;
                                    f[i][j][x] += f[i-1][y][x - ST[j].s];
                            }        
                        }
                }    
        }
        for (i = 1; i <= tot; i++) ans += f[n][i][k];
        
        printf("%lld\n",ans);
    
    return 0;
}

 

posted @ 2018-05-09 19:24  evenbao  阅读(96)  评论(0编辑  收藏  举报