Codeforces1107E. Vasya and Binary String
2024-10-08 11:50:46
题目链接
本题也是区间dp,但是需要保存的信息很多,是1还是0,有多少个连续的,那我们可以预处理,将所有的连续缩合成1个字符,那么字符串就变成了一个01交替的串,我们任意的消除1个部分,一定能引起连锁反应,像消消乐
我们设dpi,j,k为区间[i,j],j后面有k个与j相同的元素,若j与前面的i-j-1一起消,状态转移为:dpi,j,k=dpi,m,k+siz[j]+dpm+1,j-1,0,(m与j的字符相同)意思是合并i到m,m+1到j-1合并后,将i到m与j再合并,如果j单独消,dpi,j,k=dpi,j-1,0+f[siz[j]+k]
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-x))
typedef long long LL;
typedef pair<int,int> pii;
const int maxn = 105;
char s[maxn];
LL dp[maxn][maxn][maxn], f[maxn], cost[maxn];
int n, siz[maxn], bit[maxn], cnt;
void prework() {
for(int i = 1; i <= n; ++i)
for(int j = i; j <= n; ++j)
f[j] = max(f[j], f[j-i] + cost[i]);
cnt = 0;
int now = 0;
for(int i = 1; i <= n; ++i) {
if(i == 1 || s[i] == s[i-1]) ++now;
else {
siz[++cnt] = now;
bit[cnt] = s[i-1] - '0';
now = 1;
}
}
siz[++cnt] = now, bit[cnt] = s[n] - '0';
}
LL DP(int l, int r, int k) {
if(l == r) return dp[l][r][k] = f[siz[r]+k];
if(dp[l][r][k] != -1) return dp[l][r][k];
LL t = DP(l, r-1, 0) + f[siz[r] + k];
for(int i = l; i < r-1; ++i)
if(bit[i] == bit[r])
t = max(t, DP(l, i, k+siz[r])+DP(i+1, r-1, 0));
return dp[l][r][k] = t;
}
void run_case() {
cin >> n;
cin >> (s+1);
for(int i = 1; i <= n; ++i) cin >> cost[i];
prework();
memset(dp, -1, sizeof(dp));
cout << DP(1, n, 0);
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cout.flags(ios::fixed);cout.precision(10);
//int t; cin >> t;
run_case();
cout.flush();
return 0;
}
转自
https://blog.csdn.net/litble/article/details/87290658
最新文章
- 2、Redis入门介绍
- JSON相关基础知识
- django学习笔记
- AFN 无网络监控
- Hbase Java API详解
- WPF DatePicker默认显示当前日期
- [solr] - Facet - autocomplete
- MVC4发布到IIS7报404错误
- windows8 安装IIS 和 添加网站(转)
- Android SQLite总结
- pip install python 如何快速安装模块
- Python_day_01
- c3p0配置文件(c3p0.properties.xml)解读
- python 数据结构之归并排序
- linux 基本命令2(12月27日笔记)
- Android短信收到,语音播报
- 压力测试工具ab及centos下单独安装方法 nginx和tomcat静态资源的性能测试
- border-image使用过程中遇到的几个问题
- Android保持屏幕常亮
- U盘直接读写(今天用到了)