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 描述 在一个平面上,如果有两个点( ...
随机推荐
- Theano在CentOS 6 下的安装及GPU加速
系统版本:Red Hat 4.4.6-4 一. 未联网情况下,选择本地安装. 首先安装theano的依赖库,包括:scipy-0.16.1numpy-1.9.2nose-1.3.7 (optional ...
- hdu 4024 二分
转自:http://www.cnblogs.com/kuangbin/archive/2012/08/23/2653003.html 一种是直接根据公式计算的,另外一种是二分算出来的.两种方法速度 ...
- 5个让你的SaaS应用大卖的技巧
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 今天推荐的文章和具体的技术无关,但是对于创业的小伙伴应该有帮助. 去年底到今年,企业应用尤其 ...
- Lua Require函数
转自:http://www.cppblog.com/cslover/archive/2013/12/21/204934.html Lua提供高级的require函数来加载运行库.粗略的说require ...
- UVA 1328 - Period KMP
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36131 题意:给出一个长度为n的字符串,要求找到一些i,满足说从1 ...
- 安装phpmyadmin
1.查看PHP版本 新建文本文档,填写下面内容: <?phpphpinfo();?>保存,然后更改文件名为phpinfo.php放到你域名根目录,然后通过你的域名+phpinfo.php浏 ...
- 资产移动盘点手持机PDA系统
手持机PDA系统功能 PDA初始化 从后台管理机系统中预先设置的众多操作人员列表中下载当前PDA的使用人员: 系统支持多用户使用同一台PDA情况下的用户认证登陆,每一用户根据后台管理机系统设置与安全管 ...
- SGU438 The Glorious Karlutka River =)(最大流)
题目大概说有m个人要过一条宽W的河,人最远跳远距离是d,河上有n个垃圾堆,每个垃圾堆都有坐标和同一时间能容纳的人数,问所有人最少要跳几次才能跳到对岸. 又是一题根据时间拆点的最大流. 二分时间建容量网 ...
- LightOJ1122 Digit Count(DP)
dp[i][j]表示长度i末尾为S[j]的方案数 dp[1][0...m-1]=1 dp[i][j]=∑dp[i-1][k] (|S[k]-S[j]|<=2) #include<cstdi ...
- emacs auto-complete
安装的是autocomplete http://cx4a.org/software/auto-complete/ 是bz2格式压缩的 下载后 在终端输入命令 tar -xjvf auto-compl ...