NOIP模拟 偷书(状压DP)

【题目描述】

在L的书架上,有 N本精彩绝伦的书籍,每本书价值不菲。

M 是一个书籍爱好者,他对 L 的书籍早就垂涎三尺。最后他忍受不了诱惑,觉得去偷 L 的书,为了迅速完成这件事,同时他不希望 L 很快发现书籍少了,他决定偷书时,对于任意连续的 k 本书,他最多选 B 本,最少选 A 本。现在他想知道怎么选出来的书本最后使得偷的书籍的价值和,与剩下的书籍价值和,差值最大。

【输入格式】

第一行四个整数 n,k,a,b

一行 N 个整数表示每本书的价值 

【输出格式】

一个整数表示答案

【样例输入】

2 1 0 1

2 -2

【样例输出】

4

【备注】

对于 20%:n<=10 

对于另外 20%:a=0,b=k

对于 100%:n<=1000,0<=a<=b<=k<=10,所有书籍的价值的绝对值<=10^9

【题目分析】

一看到k<=10,这么小的数据简直就是宣告这是一道状压DP的题,那么就定义一个数组dp[i][j],其中i表示前i个,状态为j(包含第i个)的最大价值,易得对于每个合法dp[i][j],均可从dp[i-1][j>>1]和dp[i-1][(j>>1)|(1<<k)]转移而来,所以先预处理出所有合法情况(即1的个数大于等于a而小于等于b),最后扫一遍dp[n][k]即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
typedef long long LL;
const LL MAXN=1<<11;
const LL INF=0x3f3f3f3f;

LL dp[1001][MAXN];
LL n,k,a,b;
LL val[1001];
bool che[MAXN];

LL Read()
{
	LL i=0,f=1;
	char c;
	for(c=getchar();(c>'9'||c<'0')&&c!='-';c=getchar());
	if(c=='-')
	  f=-1,c=getchar();
	for(;c>='0'&&c<='9';c=getchar())
	  i=(i<<1)+(i<<3)+c-'0';
	return i*f;
}

void pre()
{
	for(LL i=0;i<=MAXN;++i)
	{
		LL t=i;
		LL cnt=0;
		while(t)
		{
			if(t&1)
			  cnt++;
			t>>=1;
		}
		if(cnt>=a&&cnt<=b)
		  che[i]=true;
	}
}

int main()
{
	memset(dp,INF,sizeof(dp));
	n=Read(),k=Read(),a=Read(),b=Read();
	LL ans=-dp[0][0],inf=dp[0][0];
	pre();
	LL tot=0;
	for(LL i=1;i<=n;++i)
	  val[i]=Read(),tot+=val[i];
	for(LL j=0;j<(1<<k);++j)
	  dp[0][j]=0;
	LL cs=1<<k;
	for(LL i=1;i<=n;++i)
	{
		for(LL j=0;j<cs;++j)
		{
			if(che[j])
			{
				if(dp[i-1][j>>1]!=inf&&dp[i-1][(j>>1)|(1<<(k-1))]!=inf)
				{
					if(j&1)
				      dp[i][j]=max(dp[i-1][j>>1],dp[i-1][(j>>1)|(1<<(k-1))])+val[i];
				    else
				      dp[i][j]=max(dp[i-1][j>>1],dp[i-1][(j>>1)|(1<<(k-1))]);
				}
				else
				{
					dp[i][j]=min(dp[i-1][j>>1],dp[i-1][(j>>1)|(1<<(k-1))]);
					if(dp[i][j]==inf)
					  continue;
					if(j&1)
					  dp[i][j]+=val[i];
				}
			}
		}
	}
	for(LL i=0;i<cs;++i)
	{
		if(dp[n][i]==inf)
		  continue;
		ans=max(ans,dp[n][i]);
	}
	cout<<ans*2-tot;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/g21glf/article/details/82916142
今日推荐