【轮廓线DP】2018国庆三校联考D2T1

题意:

pure 在玩一个战略类游戏。现在有一个士兵方阵,每一行有若干士兵,每个士兵属于某个兵
种。行的顺序不可改变,且每一行中士兵的顺序也不可改变。但由于每一行都有 C 个位置(C 不
小于任一行的士兵数),她能够安排每行的士兵依次站在某几个位置上。
对于每一个士兵,令其前后左右相邻四个位置上有 v 个和他种类相同的士兵,则 pure 会获得
v 的布阵分数。现在 pure 想知道她最多能够获得多少布阵分数。


分析:

轮廓线DP不扯了就是个板

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define SF scanf
#define PF printf
#define MAXS 65556
#define MAXN 130
#define MAXM 20
using namespace std;
int n,c;
int dp[2][MAXS],ans;
char s[MAXN][MAXM];
int siz[MAXN];
int count(int mask,int x,int id,int num){
	int add=0;
	if(id!=1)
		if((mask&(1<<(id-2)))&&s[x][num]==s[x][num-1])
			add++;
	int sum=__builtin_popcount(mask>>(id-1));
	int num1=siz[x-1]-sum+1;
	if((mask&(1<<(id-1)))&&s[x][num]==s[x-1][num1])
		add++;
	return add;
}
int main(){
	freopen("group.in","r",stdin);
	freopen("group.out","w",stdout);
	SF("%d%d",&n,&c);
	for(int i=1;i<=n;i++){
		SF("%s",s[i]+1);
		siz[i]=strlen(s[i]+1);
	}
	int now=0;
	for(int i=1;i<=n;i++){
		for(int mask=0;mask<(1<<c);mask++){
			if(__builtin_popcount(mask)==siz[i-1])
				dp[now][mask]=dp[now^1][mask];
			else
				dp[now][mask]=-1;
		}
		now^=1;
		for(int j=1;j<=c;j++){
			for(int mask=0;mask<(1<<c);mask++)
				dp[now][mask]=0;
			for(int mask=0;mask<(1<<c);mask++){
				if(dp[now^1][mask]==-1)
					continue;
				int x=__builtin_popcount(mask%(1<<(j-1)));
				if(x!=siz[i])
					dp[now][mask|(1<<(j-1))]=max(dp[now][mask|(1<<(j-1))],dp[now^1][mask]+count(mask,i,j,x+1));
				dp[now][mask&((1<<c)-1-(1<<(j-1)))]=max(dp[now][mask&((1<<c)-1-(1<<(j-1)))],dp[now^1][mask]);
				//PF("{%d %d %d %d}\n",i,j-1,mask,dp[i][j-1][mask]);
			}
			now^=1;
		}
	}
	for(int mask=0;mask<(1<<c);mask++)
		if(__builtin_popcount(mask)==siz[n])
			ans=max(ans,dp[now^1][mask]);
	PF("%d",ans*2);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值