P1371 NOI元丹
luogu月赛的题
本来想爆搜,但是经过ly大佬的点拨,明白这是一个dp。
我们定义dp[n]为从n开始的可行串的数目,具体如下:如果n为‘I',则是从n开始有多少个I,如果n为'O',既是从n开始有多少个’OI‘,如果n为’N‘,则是从n开始有多少个’NOI'
我们已经定义了状态,那么怎么转移呢?我们以n是‘N'为例,’NOI'的数目可以分为两部分:1)包括n, 2)不包括n。所以,我们可以这样计算dp[n],找到从n开始的第一个N和O,把两个字符的dp值相加,就得到了答案。
我们从后往前推,可以估算一下复杂度:状态数O(n),转移O(n),总的复杂度是O(n^2)。
对于每一个字串,我们都可以计算出其结果。所以下面的问题就是怎么去插。
首先,我们可以用链表来存储这一个字串,来优化一下常数;
第二,我们可以证明,对于N,把他插到最前面,一定是最优的,对于I,把他插到最后面,一定是最优的,
但是对于O我们还没有想出比较好的插法,目前的想法是去枚举。
这样在O(n2)的时间内,我们就可以算出。
ly大佬用这个算法得了60分。。。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 200;
int n;
string str;
int cnt;
int table[maxn];
int ans[maxn];
int tmp[maxn];
//==============
int value[maxn];
int count() {
int pos = n - 1;
int i, j;
if(tmp[n] == 2) value[n] = 1;
else value[n] = 0;
while(pos != -1) {
if(tmp[pos] == 2) {
for(i = pos+1; i <= n; i++) {
if(tmp[i] == tmp[pos]) break;
}
value[pos] = value[i] + 1;
}
else if(tmp[pos] == 1) {
for(i = pos+1; i <= n; i++) {
if(tmp[i] == 1) break;
}
for(j = pos+1; j <= n; j++) {
if(tmp[j] == 2) break;
}
value[pos] = value[i] + value[j];
}
else if(tmp[pos] == 0) {
for(i = pos+1; i <= n; i++) {
if(tmp[i] == 1) break;
}
for(j = pos+1; j <= n; j++) {
if(tmp[j] == 0) break;
}
value[pos] = value[i] + value[j];
}
pos--;
}
for(i = 0; i < n; i++) {
if(tmp[i] == 0) break;
}
return value[i];
}
//==============
int main(int argc, char const *argv[])
{
cin >> n >> str;
memset(value, 0, sizeof(value));
for(int i = 0; i <= n;i++) {
if(str[i] == 'N') table[i] = 0;
else if(str[i] == 'O') table[i] = 1;
else if(str[i] == 'I') table[i] = 2;
}
tmp[0] = 0;
for(int i = 1; i <= n+1;i++) tmp[i] = table[i-1];
int a = count();
for(int i = 1; i <= n+1;i++) tmp[i] = table[i];
tmp[n+1] = 2;
int b = count();
int i, k;
for(k = n; k >= 0; k--) if(table[k] == '1') break;
for(i = 0;i <= k; i++) {
tmp[i] = table[i];
}
tmp[i] = 1;
for(;i<=n;i++) {
tmp[k] = table[k-1];
}
int c = count();
cout << max(max(a, b), c);
return 0;
}
/*void dfs(int choose, int pos) {
if(choose == n){
cnt++;return;}
if(pos == str.size()) return;
for(int i = pos; i <= str.size(); i++) {
if(tmp[i] == choose) {
ans[choose] = i;
dfs(choose + 1, i+1);}
}
}
int count() {
cnt = 0;
dfs(0, 0);
return cnt;
}*/
/*cin >> n >> str;
int maxx = 0;
for(int i = 0; i <= str.size();i++) {
if(str[i] == 'N') table[i] = 0;
else if(str[i] == 'O') table[i] = 1;
else if(str[i] == 'I') table[i] = 2;
}
int k;
for(int i = 0; i < 3; i++) {
for(int j = 0; j <= n; j++) {
for(k = 0; k <= j; k++) {
tmp[k] = table[k];
}
tmp[k] = i;
for(;k<=n;k++) {
tmp[k] = table[k-1];
}
maxx = max(maxx, count());
}
}
cout << maxx;*/
54 NONOONIONIINIOOONONIIIINNONOINOONNOOIIOIOIOIINONNNIOON
10 ONNINNONNI
P1371 NOI元丹的更多相关文章
- 洛谷P1371 NOI元丹
P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交 讨论 题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...
- 洛谷10月月赛Round.3
Rank11:260=60+100+100 P2409 Y的积木 题目背景 Y是个大建筑师,他总能用最简单的积木拼出最有创意的造型. 题目描述 Y手上有n盒积木,每个积木有个重量.现在他想从每盒积木中 ...
- 从一道NOI练习题说递推和递归
一.递推: 所谓递推,简单理解就是推导数列的通项公式.先举一个简单的例子(另一个NOI练习题,但不是这次要解的问题): 楼梯有n(100 > n > 0)阶台阶,上楼时可以一步上1阶,也可 ...
- NOI 动态规划题集
noi 1996 登山 noi 8780 拦截导弹 noi 4977 怪盗基德的滑翔翼 noi 6045 开餐馆 noi 2718 移动路线 noi 2728 摘花生 noi 2985 数字组合 no ...
- noi 6047 分蛋糕
题目链接:http://noi.openjudge.cn/ch0405/6047/ 和Uva1629很类似,不过,可能用记忆化难写一点,状态初始化懒得搞了.就用循环好了. 状态描叙也可以修改,那个题目 ...
- NOI 2015 荷马史诗【BZOJ 4198】k叉Huffman树
抱歉因为NOIP集训,好长时间没再写题解了. NOI 2015也就只有这道题一看就能懂了-- 4198: [Noi2015]荷马史诗 Time Limit: 10 Sec Memory Limit: ...
- noi题库(noi.openjudge.cn) 1.7编程基础之字符串T31——T35
T31 字符串P型编码 描述 给定一个完全由数字字符('0','1','2',-,'9')构成的字符串str,请写出str的p型编码串.例如:字符串122344111可被描述为"1个1.2个 ...
- NOI WC2016滚粗记
Day-4 报到日,今年居然没有发包QAQ,中午到的,志愿者很热情,食堂吃不了(也有可能是吃不惯),空调打不热,有拖线板(好评),有wifi覆盖(虽然听说连上要看脸)(反正我是没连过,用的自己的流量) ...
- NOI题库刷题日志 (贪心篇题解)
这段时间在NOI题库上刷了刷题,来写点心得和题解 一.寻找平面上的极大点 2704:寻找平面上的极大点 总时间限制: 1000ms 内存限制: 65536kB 描述 在一个平面上,如果有两个点( ...
随机推荐
- poj 1273 最大流入门
明天再拍一遍 #include <iostream> #include <queue> using namespace std; ; const int INF = 0x7FF ...
- emacs入门
emacs入门 复制: 用Ctrl-@ 设置起点, 然后移动光标到终点, 为了确认你的起点和终点,可以用 C-x C-x 将光标在起点和终点间切换,如果没问题了,可以用 Alt-w 来复制. 再找一个 ...
- poj 1611 The Suspects 并查集
The Suspects Time Limit: 1000MS Memory Limit: 20000K Total Submissions: 30522 Accepted: 14836 De ...
- js:语言精髓笔记5----语言分类
计算模型:源于对计算过程的不同认识: 1.基于不同计算模型一般分为://教科书的一般分类 命令式语言: 函数式语言: 逻辑式语言: 面向对象程序设计语言: 2.基于程序本质分类: //编程的经典法则 ...
- 自爽:DOTNET 笔试题
2-3年经验估计,求轻拍~ 在多态中,经常用到virtual和abstract,请问区别是什么?并描述其适用场景. 请描述Action,Action<T>,Func<T>,Fu ...
- SplendidCRM 如何添加及使用中文语言包
SplendidCRM 功能很强大,也支持多国语言,但关于中文语言安装的介绍在网上一直都找到,自已摸索了一下,成功使SplendidCRM应用中文,以下是安装方法. 版本号:SplendidCRM 7 ...
- jpeglib使用指南
您可以到http://www.ijg.org/网站下载libjpeg的源码, IJG JPEG Library就是jpeg压缩库,是以源码的形式提供给软件开发人员的,当然在软件包里也有编译好的库文件, ...
- LeetCode-Repeated DNA Sequences (位图算法减少内存)
Repeated DNA Sequences All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, ...
- JBPM4.4学习API
一.流程引擎API org.jbpm.api.ProcessEngine是jbpm4所有的Service API 之源. 既所有的Service API(服务接口)都从ProcessEngine中获取 ...
- java截取图片部分尺寸
package util; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.File; i ...