题解 特殊字符串

传送门

处理 \(tran[i][j]\) 表示在 \(i\) 后面接 \(j\) 的贡献,然后按题意DP

Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
//#define int long long

int n, m;
ll tran[30][30];
char s[N], t1[10], t2[10];

namespace force{
	int tot;
	ll ans;
	char tem[N];
	ll check() {ll ans=0; for (int i=2; i<=tot; ++i) ans+=tran[tem[i-1]-'a'][tem[i]-'a']; return ans;}
	void dfs(int u) {
		if (u>n) {
			ans=max(ans, check());
			return ;
		}
		dfs(u+1);
		tem[++tot]=s[u];
		dfs(u+1);
		--tot;
	}
	void solve() {
		dfs(1);
		printf("%lld\n", ans);
		exit(0);
	}
}

namespace task1{
	ll dp[N][30], ans;
	void solve() {
		for (int i=0; i<26; ++i) dp[1][i]=-1e16;
		dp[1][s[1]-'a']=0;
		for (int i=2; i<=n; ++i) {
			for (int j=0; j<26; ++j) {
				if (j==s[i]-'a') for (int k=0; k<26; ++k) dp[i][j]=max(dp[i][j], dp[i-1][k]+tran[k][j]);
				else dp[i][j]=dp[i-1][j];
			}
		}
		for (int i=0; i<26; ++i) ans=max(ans, dp[n][i]);
		printf("%lld\n", ans);
		exit(0);
	}
}

signed main()
{
	freopen("shiki.in", "r", stdin);
	freopen("shiki.out", "w", stdout);

	scanf("%d%s%d", &n, s+1, &m);
	for (int i=1,k; i<=m; ++i) {
		scanf("%s%s%d", t1, t2, &k);
		tran[(*t1)-'a'][(*t2)-'a']+=k;
	}
	// force::solve();
	task1::solve();

	return 0;
}
posted @ 2021-10-31 10:17  Administrator-09  阅读(0)  评论(0编辑  收藏  举报