ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021牛客OI赛前集训营-提高组(第五场)C-第K排列【dp】

2021-10-14 07:31:32  阅读:164  来源: 互联网

标签:字符 include OI 第五场 ll dfs leq 权值 集训营


正题

题目链接:https://ac.nowcoder.com/acm/contest/20110/C


题目大意

一个长度为\(n\)的字符串\(S\),\(S\)中存在一些\(?\),有\(N/O/I/P\)四个字符作为字符集,每对相邻的字符会产生不同的贡献,现在要求所有权值不小于\(x\)的字符串中字典序第\(k\)大的。

\(1\leq n,k\leq 1000,1\leq x\leq 10^9\)


解题思路

考虑到暴力\(dfs\)搜索的瓶颈在于我们可能会搜到大量权值小于\(x\)的序列,所以如果保证我们每次都能搜到满足条件的字符我们就可以\(O(nk)\)解决这个问题。

可以设\(f_{i,j}\)表示\(i\)个字符是\(j\)开始往后最多能得到多少权值。

然后根据\(dp\)数组暴力\(dfs\)就好了。

时间复杂度:\(O(nk)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=1100;
ll n,l,k,w[4][4],f[N][4],a[N],c[N];
char s[N];
void dfs(ll x,ll p,ll sum){
	if((c[x]!=-1&&c[x]!=p)||sum+f[x][p]<l||!k)return;
	a[x]=p;
	if(x==n&&sum>=l){
		k--;
		if(!k){
			for(ll i=1;i<=n;i++){
				if(a[i]==0)putchar('N');
				if(a[i]==1)putchar('O');
				if(a[i]==2)putchar('I');
				if(a[i]==3)putchar('P');
			}
			putchar('\n');
		}
		return;
	}
	dfs(x+1,3,sum+w[p][3]);
	dfs(x+1,1,sum+w[p][1]);
	dfs(x+1,0,sum+w[p][0]);
	dfs(x+1,2,sum+w[p][2]);
	return;
}
signed main()
{
	scanf("%lld%lld%lld",&n,&l,&k);
	scanf("%s",s+1);
	for(ll i=1;i<=n;i++){
		if(s[i]=='N')c[i]=0;
		if(s[i]=='O')c[i]=1;
		if(s[i]=='I')c[i]=2;
		if(s[i]=='P')c[i]=3;
		if(s[i]=='?')c[i]=-1;
	}
	for(ll i=0;i<4;i++)
		for(ll j=0;j<4;j++)
			scanf("%lld",&w[i][j]);
	memset(f,0xcf,sizeof(f));
	for(ll i=0;i<4;i++)
		if(c[n]==-1||c[n]==i)f[n][i]=0;
	for(ll i=n-1;i>=1;i--)
		for(ll j=0;j<4;j++){
			if(!(c[i]==-1||c[i]==j))continue;
			for(ll k=0;k<4;k++)
				f[i][j]=max(f[i][j],f[i+1][k]+w[j][k]);
		}
	dfs(1,3,0);dfs(1,1,0);dfs(1,0,0);dfs(1,2,0);
	if(k)puts("-1");
	return 0;
}

标签:字符,include,OI,第五场,ll,dfs,leq,权值,集训营
来源: https://www.cnblogs.com/QuantAsk/p/15405016.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有