hihocoder #1044 : 状态压缩·一 状压DP

本文介绍了一个使用动态规划解决的问题:给定一定数量的座位及每座位的垃圾处理能力,求最大垃圾处理量。该问题的关键在于理解每一位的选择只依赖于前m位的状态,通过将这些状态转化为01序列并进行状态转移实现。

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

http://hihocoder.com/problemset/problem/1044

可以看出来每一位的选取只与前m位有关,我们把每个位置起始的前m位选取状态看出01序列,就可以作为一个数字来存储,那么将其作为状态,dp[i][j]就是第i个座位前m个座位选取情况为j的最大垃圾处理量。然后取这个序列的后m-1位,和当前位取0/1的情况分别做合法性判断,然后做状态转移即可。

#include <iostream>
using namespace std;
const int N=1005;
const int inf=99999999;
int dp[N][2000];
int n,m,q;
int w[N];
int cntb(int num)
{
    int c=0;
    while(num)
        c+=num%2,num>>=1;
    return c;
}
int main()
{
    cin.sync_with_stdio(false);
    while(cin>>n>>m>>q)
    {
        for(int i=1; i<=n; i++)
            cin>>w[i];
        for(int i=0; i<(1<<m); i++)
            dp[0][i]=-inf;
        dp[0][0]=0;
        int d=1<<(m-1);
        for(int i=1; i<=n; i++)
        {
            for(int j=0;j<(1<<m);j++)
                dp[i][j]=-inf;
            for(int j=0;j<(1<<m);j++)
            {
                int qc=cntb(j>>1);
                if(qc>q)continue;
                if(qc==q)dp[i][j>>1]=max(dp[i][j>>1],dp[i-1][j]);
                else
                {
                    dp[i][d+(j>>1)]=max(dp[i][d+(j>>1)],dp[i-1][j]+w[i]);
                    dp[i][j>>1]=max(dp[i][j>>1],dp[i-1][j]);
                }
            }
        }
        int ans=-inf;
        for(int i=0;i<(1<<m);i++)
          ans=max(dp[n][i],ans);
        cout<<ans<<endl;
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/LukeStepByStep/p/8351359.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值