【BZOJ1087】【SCOI2005】互不侵犯King 状态压缩 动态规划 水题 都不用加特技

本文介绍如何使用裸状压DP(Dynamic Programming)解决一道简单的编程问题。首先阐述了题目的背景,然后详细解释了如何通过状态转移方程来求解最优解,并附上了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

广告:

#include <stdio.h>
int main()
{
    puts("转载请注明出处[vmurder]谢谢");
    puts("网址:blog.youkuaiyun.com/vmurder/article/details/44022265");
}

题解:

一开始让我写这道题,其实我是,是接受的。
BalaBala。
毕竟水题,都不用特技。

裸状压DP。
直接f[i][j][k]表示第i行状态时j,有k个落子时的方案数。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 10
#define M 1200
using namespace std;
int n,m,sum;
long long f[N][M][N*N];
int str[M],num[M],cnt;
bool check(int S,int T)
{
    return ((S&T)|(S&(T<<1))|(S&(T>>1)));
}
int main()
{
//  freopen("test.in","r",stdin);
    int i,j,k,l;
    f[0][1][0]=1;
    scanf("%d%d",&n,&m);
    sum=1<<n;
    for(i=0;i<sum;i++)
    {
        if((i&(i<<1))==0)
        {
            str[++cnt]=i;
            k=i,l=0;
            while(k)
            {
                l+=(k&1);
                k>>=1;
            }
            num[cnt]=l;
        }
    }
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=cnt;j++)
        {
            for(k=1;k<=cnt;k++)if(!check(str[j],str[k]))
            {
                for(l=num[k];l<=m;l++)
                {
                    f[i][k][l]+=f[i-1][j][l-num[k]];
                }
            }
        }
    }
    long long ans=0;
    for(i=1;i<=cnt;i++)ans+=f[n][i][m];
    cout<<ans<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值