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. 微信jsapi接口测试

    微信jsapi接口测试 <?php require_once 'lib.inc.php'; $wx = new WxApi(); if(!isset($_GET['code'])){ heade ...

  2. SQL_Server_2005_函数大全(描述及实例)

    为了方便阅读,把函数分为四种类型,分别表述. SQL_Server_2005_字符串函数(描述及实例) 函数名称:ascii.char.charindex.difference.left.right. ...

  3. DFS/BFS Codeforces Round #301 (Div. 2) C. Ice Cave

    题目传送门 /* 题意:告诉起点终点,踩一次, '.'变成'X',再踩一次,冰块破碎,问是否能使终点冰破碎 DFS:如题解所说,分三种情况:1. 如果两点重合,只要往外走一步再走回来就行了:2. 若两 ...

  4. SVN标准命令

    SVN标准命令 范例 checkout 检出 svn  co  URL 检出app/search/news/apache/主干上最新版本到本地工作副本,可执行命令: svn co  https://s ...

  5. 【BZOJ】1927: [Sdoi2010]星际竞速(费用流)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1927 题意:n个点的无向图.m条加权边.只能从编号小的到编号大的.可以瞬移,瞬移有时间.每个点只能访 ...

  6. 【NOI2015】荷马史诗

    追逐影子的人,自己就是影子. ——荷马 Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>.但是由<奥德赛>和& ...

  7. 定时任务之Spring与Quartz的整合(有修改)

    转摘:http://www.javaweb1024.com/java/JavaWebzhongji/2015/04/13/548.html 在Spring中使用Quartz有两种方式实现:第一种是任务 ...

  8. css 框架——base.css,作用是重设浏览器默认样式和提供通用原子类。自己留存

    今天发下我自己的 css 框架——base.css,作用是重设浏览器默认样式和提供通用原子类. @charset "utf-8"; /*! * @名称:base.css * @功能 ...

  9. Highcharts 本地导出图片 Java

    下载的Highcharts-2.3.5.zip 解压后 有 E:\Highcharts\Highcharts-2.3.5\exporting-server\java 目录 提供了Java实现的导出应用 ...

  10. event.keycode大全(javascript)

    keycode 8 = BackSpace BackSpace keycode 9 = Tab Tab keycode 12 = Clear keycode 13 = Enter keycode 16 ...