seq(2018.10.24)
一道\(dp\)题。。。
期望\(40\)分解法
预处理:离散化,然后让连续一段值相同的元素合并为一个元素。
正式\(DP\):
显然有个最差策略为每个元素处都切一次,则切的次数为元素的个数\(-1\)
相对地来说就是假设全部元素之间就已经切开,要尽量多地合并元素
\(DP\)的第一维用来确认当前是合并了值为多少的两个数值段,DP的第二维来记住最后一次合并是合并了哪个位置的两个线段
即\(DP[i][j]=\)对于值为\(1\)到\(i+1\)的数值段, 最后一次合并为合并\(a[j]\)和\(a[j+1]\)这两个元素,最多能合并的总次数
而相对应的转移方程就是:
\(DP[i][j] =max( DP[i-1][j']+1) (合并 a[j'] , a[j'+1] 不会与 合并a[j],a[j+1]冲突)\)
冲突是指合并\(a[i],a[i+1]\)的同时也合并\(a[j],a[j+1]\)会导致无法拼接成单调不降的序列,其充要条件是\(i+1=j\)且值为\(a[i+1]\)的数值段在原序列中出现了不止\(1\)次,
空间和时间复杂度都是\(O(n^2)\),期望得分\(40\)分
期望\(100\)分解法
优化:
\(1.\)滚动数组优化空间为\(O(n)\)
\(2.\)因为对于每个\(i=x\),转移的时候只用考虑最大值和次大值,如果最大值和当前状态冲突,则用次大值更新
空间和时间复杂度都是\(O(n)\),期望得分\(100\)分
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
int n,a[100001],cnt,b[100001],tot,pre[100001],nxt[100001],h[100001],deg[100001];
pair<int,int>dp[2],DP[2];
map<int,int>mp;
void add(int x,int y){pre[++cnt]=y;nxt[cnt]=h[x];h[x]=cnt;deg[x]++;}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];
sort(b+1,b+n+1);
for(int i=1;i<=n;i++)if(!mp[b[i]])mp[b[i]]=++tot;
for(int i=1;i<=n;i++)a[i]=mp[a[i]];tot=0;
for(int i=1;i<=n;i++)if(a[i]!=a[i+1])a[++tot]=a[i];
for(int i=1;i<=tot;i++)add(a[i],i);
for(int i=h[1];i;i=nxt[i])
if(a[pre[i]+1]==2)
{
dp[1]=max(dp[1],make_pair(1,pre[i]));
if(dp[1]>DP[1])swap(dp[1],DP[1]);
}
for(int i=2;i<cnt;i++)
{
dp[i&1]=dp[(i&1)^1];DP[i&1]=DP[(i&1)^1];
for(int j=h[i];j;j=nxt[j])
if(a[pre[j]+1]==a[pre[j]]+1)
{
if(DP[(i&1)^1].second+1!=pre[j]||deg[i]==1)dp[i&1]=max(dp[i&1],make_pair(DP[(i&1)^1].first+1,pre[j]));
else dp[i&1]=max(dp[i&1],make_pair(dp[(i&1)^1].first+1,pre[j]));
if(dp[i&1]>DP[i&1])swap(dp[i&1],DP[i&1]);
}
}
printf("%d\n",tot-1-DP[(cnt-1)&1].first);
}
seq(2018.10.24)的更多相关文章
- python中使用Opencv进行车牌号检测——2018.10.24
初学Python.Opencv,想用它做个实例解决车牌号检测. 车牌号检测需要分为四个部分:1.车辆图像获取.2.车牌定位.3.车牌字符分割和4.车牌字符识别 在百度查到了车牌识别部分车牌定位和车牌字 ...
- 2018.10.24 NOIP2018模拟赛 解题报告
得分: \(100+0+100=200\)(\(T2\)悲惨爆\(0\)) \(P.S.\)由于原题是图片,所以我没有上传题目描述,只有数据. \(T1\):query(点此看题面) 熟悉主席树的人都 ...
- 课堂笔记及知识点----树(2018/10/24(pm))
树 概念:由一个或多个(n≥0)结点组成的有限集合 T, 有且仅有一个结点称为根( root), 当 n>1时,其余的结点分为 m(m≥0)个互不相交的有限集合 T1,T2, …, Tm.每个集 ...
- 课堂笔记及知识点----栈和队列(2018/10/24(am))
栈: Stack<int> xt=new Stack<int>() ; 先进后出,后进先出,水杯结构,顺序表类似 常用方法: .pop---->出栈,弹栈 ...
- 2018.10.24 bzoj3195: [Jxoi2012]奇怪的道路(状压dp)
传送门 f[i][j][k]f[i][j][k]f[i][j][k]表示前iii个点连了jjj条边,第i−K+1i-K+1i−K+1~iii个点连边数的奇偶性为kkk时的方案数. 转移规定只能从后向前 ...
- 2018.10.24 bzoj2064: 分裂(状压dp)
传送门 状压dp好题. 考虑对于两个给出的集合. 如果没有两个元素和相等的子集,那么只能全部拼起来之后再拆开,一共需要n1+n2−2n1+n2-2n1+n2−2. 如果有呢? 那么对于没有的就是子问题 ...
- 2018.10.24 NOIP模拟 小 C 的宿舍(分治)
传送门 分治妙题. 没有这道题的暴力分今天又垫底了啊233 由于用了分治的方法,我们只用考虑左区间对右区间的贡献以及右区间对左区间的贡献. 可以发现如果从中点开始向两边递推最小值并用这个区间最小值来推 ...
- 2018.10.24 NOIP模拟 小 C 的序列(链表+数论)
传送门 考虑到a[l],gcd(a[l],a[l+1]),gcd(a[l],a[l+1],a[l+2])....gcd(a[l]...a[r])a[l],gcd(a[l],a[l+1]),gcd(a[ ...
- 2018.10.24 NOIP模拟 小 C 的数组(二分+dp)
传送门 考试自己yyyyyy的乱搞的没过大样例二分+dp二分+dp二分+dp过了606060把我自己都吓到了! 这么说来乱搞跟被卡常的正解比只少101010分? 那我考场不打其他暴力想正解血亏啊. 正 ...
随机推荐
- OI中字符串读入和处理
OI中字符串读入和处理 在NOIP的"大模拟"题中,往往要对字符串进行读入并处理,这些字符串有可能包含空格并以\n作为分割,传统的cin >> scanf() 等等,不 ...
- firefox coap安装使用
coap 插件: 百度搜索firefox coap也能找到该插件https://addons.mozilla.org/zh-CN/firefox/addon/copper-270430/在firefo ...
- objective-c的代码块block
一.block 1.bock是由于^开头,括号里面填写参数类型. 标准代码块: 返回值 (^代码块名称) (参数类型) = ^(参数) {方法体}; 2.我们的块即可以定义在函数内或者对象 ...
- Ace(二)Demo示例
Client: #include "ace/Log_Msg.h" #include "ace/OS.h" #include "ace/Service_ ...
- Vue的watch和computed属性
Vue的watch属性 Vue的watch属性可以用来监听data属性中数据的变化 <!DOCTYPE html> <html> <head> <meta c ...
- webrtc 学习资源
http://www.cnblogs.com/lingyunhu/tag/webrtc%20android%20ios/
- nyoj 86 --位标记
nyoj 86 --位标记 点击打开题目链接 : 找球号(一) 这道题目很多解法,其他解法请参考 http://www.cnblogs.com/play ...
- 【linux】lsof命令和{Linux下文件删除、句柄与空间释放问题}
导读: 一.用事实说话 二.关于LSOF命令的其它用法: 三.参考文档: 正文: lsof:Finding open files with lsof 作用:查看文件被哪些进程打开 一.用事实说 ...
- maven目录结构
groupId的值是项目的包名 artifactId的值是模块名,建议使用项目名
- 51nod 1327 棋盘游戏——延迟决策的dp
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1327 因为一列填1个或0个(或0个!!!),而一行不知填多少个,所 ...