列表

详情


NC25229. 神秘的字符串

描述

        某华大学的漂亮小姐姐Anna得到了一个字符串s,她很好奇的看着这个字符串,然而,这个字符串有点害羞。这下,Anna更好奇了。

        在Anna好奇的大眼睛注视下,字符串s偏着脸说出了它的秘密。

        “我们每一个字符串都有它的价值。嗯,这个价值有它衡量的标准。我是一个只含有0,1的字符串,我的衡量标准是可以删除一段连续的0或者1,删除后,剩下的拼接到一起(举个栗子,011110,如果我删除第3、4位连续的两个1后,就剩下0110),如果我删除的长度为a,我可以得到va的价值。我可以删除任意次数,直到全部删完。现在,我的秘密就是所有操作后得到的价值的总和的最大值。你,知道我的秘密是多少吗?”

        “好像有点难啊?”Anna歪着脑袋说。

输入描述

    输入包括三行。
    第一行包括一个整数n(表示这个字符串的长度)。
    第二行是这个字符串。(保证只由0,1组成且只有n个字符)。
    第三行,包括n个整数v1,v2,…,vi,vi+1,…,vn。vi表示删除i位连续的字符会得到vi大小的价值。(0<n<=100,0<vi<=1000000000)。

输出描述

每组测试数据输出一行,为可以得到的最大价值。

示例1

输入:

7
1101001
3 4 9 100 1 2 3

输出:

109

示例2

输入:

5
10101
3 10 15 15 15

输出:

23

示例3

输入:

5
11111
100 1 1 1 1

输出:

500

说明:

对于样列三,我们没有必要删除连续两位或者三位,四位,五位的1(虽然我们可以这么做)。因为我将五个1分开删除我们就可以得到最大的价值。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 57ms, 内存消耗: 9500K, 提交时间: 2023-03-29 10:07:22

#include <iostream>
#include <cstring>
using namespace std;

const int N=105;
long long dp[N][N][N];
int a[N];
char s[N];

long long dfs(int l, int r, int k)
{
	if(l>r) return 0;
	if(~dp[l][r][k])
		return dp[l][r][k];
	dp[l][r][k]=dfs(l, r-1, 1)+a[k];
	for(int i=r-1; i>=l; i--)
		if(s[r]==s[i])
			dp[l][r][k]=max(dp[l][r][k], dfs(l, i, k+1)+dfs(i+1, r-1, 1));
    return dp[l][r][k];
}

int main()
{
	int n; scanf("%d", &n);
	scanf("%s", s+1);
	memset(dp,-1,sizeof(dp));
	for(int i=1; i<=n; i++) scanf("%d", &a[i]);
	cout << dfs(1, n, 1) << '\n';
	return 0;
}

C++14(g++5.4) 解法, 执行用时: 68ms, 内存消耗: 10980K, 提交时间: 2019-04-21 10:49:44

#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define ll long long
using namespace std;
const int N=110;
int n,a[N]; ll f[N][N][N]; char s[N];
ll dfs(int l,int r,int k){
	if (l>r) return 0;
	if (~f[l][r][k]) return f[l][r][k];
	ll res=a[k]+dfs(l+1,r,1);
	rep (i,l+1,r) if (s[i]==s[l]) res=max(res,dfs(l+1,i-1,1)+dfs(i,r,k+1));
	return f[l][r][k]=res;
}
int main(){
	scanf("%d%s",&n,s+1);
	rep (i,1,n) scanf("%d",&a[i]);
	memset(f,-1,sizeof(f));
	cout<<dfs(1,n,1)<<'\n';
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 63ms, 内存消耗: 9568K, 提交时间: 2019-04-21 17:10:42

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int val[105],n;
char s[105];
ll f[105][105][105];

ll dfs(int l,int r,int k)
{
	if(l>r)
		return 0;
	if(f[l][r][k]!=-1)
		return f[l][r][k];
	ll ans=val[k]+dfs(l+1,r,1);
	for(int i=l+1;i<=r;i++)
		if(s[i]==s[l])
			ans=max(ans,dfs(l+1,i-1,1)+dfs(i,r,k+1));
	return f[l][r][k]=ans;
}

int main()
{
	scanf("%d%s",&n,s+1);
	for(int i=1;i<=n;i++)
		scanf("%d",&val[i]);
	memset(f,-1,sizeof(f));
	printf("%lld\n",dfs(1,n,1));
}

上一题