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元丹的更多相关文章

  1. 洛谷P1371 NOI元丹

    P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交  讨论  题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...

  2. 洛谷10月月赛Round.3

    Rank11:260=60+100+100 P2409 Y的积木 题目背景 Y是个大建筑师,他总能用最简单的积木拼出最有创意的造型. 题目描述 Y手上有n盒积木,每个积木有个重量.现在他想从每盒积木中 ...

  3. 从一道NOI练习题说递推和递归

    一.递推: 所谓递推,简单理解就是推导数列的通项公式.先举一个简单的例子(另一个NOI练习题,但不是这次要解的问题): 楼梯有n(100 > n > 0)阶台阶,上楼时可以一步上1阶,也可 ...

  4. NOI 动态规划题集

    noi 1996 登山 noi 8780 拦截导弹 noi 4977 怪盗基德的滑翔翼 noi 6045 开餐馆 noi 2718 移动路线 noi 2728 摘花生 noi 2985 数字组合 no ...

  5. noi 6047 分蛋糕

    题目链接:http://noi.openjudge.cn/ch0405/6047/ 和Uva1629很类似,不过,可能用记忆化难写一点,状态初始化懒得搞了.就用循环好了. 状态描叙也可以修改,那个题目 ...

  6. NOI 2015 荷马史诗【BZOJ 4198】k叉Huffman树

    抱歉因为NOIP集训,好长时间没再写题解了. NOI 2015也就只有这道题一看就能懂了-- 4198: [Noi2015]荷马史诗 Time Limit: 10 Sec  Memory Limit: ...

  7. noi题库(noi.openjudge.cn) 1.7编程基础之字符串T31——T35

    T31 字符串P型编码 描述 给定一个完全由数字字符('0','1','2',-,'9')构成的字符串str,请写出str的p型编码串.例如:字符串122344111可被描述为"1个1.2个 ...

  8. NOI WC2016滚粗记

    Day-4 报到日,今年居然没有发包QAQ,中午到的,志愿者很热情,食堂吃不了(也有可能是吃不惯),空调打不热,有拖线板(好评),有wifi覆盖(虽然听说连上要看脸)(反正我是没连过,用的自己的流量) ...

  9. NOI题库刷题日志 (贪心篇题解)

    这段时间在NOI题库上刷了刷题,来写点心得和题解 一.寻找平面上的极大点 2704:寻找平面上的极大点 总时间限制:  1000ms  内存限制:  65536kB 描述 在一个平面上,如果有两个点( ...

随机推荐

  1. poj 1273 最大流入门

    明天再拍一遍 #include <iostream> #include <queue> using namespace std; ; const int INF = 0x7FF ...

  2. emacs入门

    emacs入门 复制: 用Ctrl-@ 设置起点, 然后移动光标到终点, 为了确认你的起点和终点,可以用 C-x C-x 将光标在起点和终点间切换,如果没问题了,可以用 Alt-w 来复制. 再找一个 ...

  3. poj 1611 The Suspects 并查集

    The Suspects Time Limit: 1000MS   Memory Limit: 20000K Total Submissions: 30522   Accepted: 14836 De ...

  4. js:语言精髓笔记5----语言分类

    计算模型:源于对计算过程的不同认识: 1.基于不同计算模型一般分为://教科书的一般分类 命令式语言: 函数式语言: 逻辑式语言: 面向对象程序设计语言: 2.基于程序本质分类:  //编程的经典法则 ...

  5. 自爽:DOTNET 笔试题

    2-3年经验估计,求轻拍~ 在多态中,经常用到virtual和abstract,请问区别是什么?并描述其适用场景. 请描述Action,Action<T>,Func<T>,Fu ...

  6. SplendidCRM 如何添加及使用中文语言包

    SplendidCRM 功能很强大,也支持多国语言,但关于中文语言安装的介绍在网上一直都找到,自已摸索了一下,成功使SplendidCRM应用中文,以下是安装方法. 版本号:SplendidCRM 7 ...

  7. jpeglib使用指南

    您可以到http://www.ijg.org/网站下载libjpeg的源码, IJG JPEG Library就是jpeg压缩库,是以源码的形式提供给软件开发人员的,当然在软件包里也有编译好的库文件, ...

  8. LeetCode-Repeated DNA Sequences (位图算法减少内存)

    Repeated DNA Sequences All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, ...

  9. JBPM4.4学习API

    一.流程引擎API org.jbpm.api.ProcessEngine是jbpm4所有的Service API 之源. 既所有的Service API(服务接口)都从ProcessEngine中获取 ...

  10. java截取图片部分尺寸

    package util; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.File; i ...