hihoCoder1044 (状态压缩DP)

分析:状态压缩DP。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int w[2000],dp[1001][1<<11];
/*int sum(int x)
{
    int ans=0;
    while(x)
    {
        ans+=x%2;x/=2;
    }
    return ans;
}*/
int sum(int x)  
{  
    int ans=0;  
    while(x>0)  
    {
        ans+=(x&1);  
        x>>=1;  
    }  
    return ans;  
} 
int main()
{
    int N,M,Q;
    scanf("%d%d%d",&N,&M,&Q);
    for(int i=1;i<=N;i++) scanf("%d",&w[i]);
/*dp[i][S]表示位置i到i-m+1这m个位置状态为S时的最大清扫数量
当S中的1等于Q时,第i个位置就不能选取,dp[i][S]=max(dp[i-1][S>>1],dp[i-1][S>>1+(1<<m-1)])
S第0位即表示i是否选取 
*/
    for(int i=1;i<=N;i++)
    {
        for(int S=0;S<(1<<min(i,M));S++)
        if(sum(S)<=Q)
        {
            if(S&1)//第i位被选中 
                dp[i][S]=max(dp[i-1][S>>1],dp[i-1][(S>>1)+(1<<M-1)])+w[i];
            else //第i位不被选中
                dp[i][S]=max(dp[i-1][S>>1],dp[i-1][(S>>1)+(1<<M-1)]);
        }
    }
    
    int ans=dp[N][0];
    for(int i=1;i<(1<<min(N,M));i++)
    ans=max(ans,dp[N][i]);
    printf("%d
",ans);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/ACRykl/p/8401400.html