[SCOI2014]方伯伯的玉米田 //二维树状数组优化DP
题目:
方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美。这排玉米一共有N株,它们的高度参差不齐。方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感的玉米拔除掉,使得剩下的玉米的高度构成一个单调不下降序列。方伯伯可以选择一个区间,把这个区间的玉米全部拔高1单位高度,他可以进行最多K次这样的操作。拔玉米则可以随意选择一个集合的玉米拔掉。问能最多剩多少株玉米,来构成一排美丽的玉米
n<=10000 , k <= 500
我第一眼想差分,但是发现不可做,因为我不会在差分上跑最长不降子序列╮( ̄⊿ ̄")╭
仔细思考一会之后看了题解好像有个好性质:
对于最优解,拔高区间右界必须为n
其实很显然(那你为什么看题解),如果拔高时不带上右边的玉米,显然对右边的玉米能否加入序列不利,而拔高时带上右边的玉米是“免费的”,
发现这个性质后,这个DP突然变得很简单,我挑出来一个序列,序列中“降”的值不超过k,就像这样
没错 这图是我画的 不然怎么能这么丑
突然很清晰了有没有?
这里我们可以自己可以口胡出来方程,dp[以第i个为结尾的序列][用了k次拔高] = 这个序列的长度
转移为dp[i][k] = max(dp[j][k-q]+1,dp[i][k])其中q为需要拔高多少(如果不用则为0),j为i前的玉米
欢欢喜喜写完过样例一交10pts,剩下全 泰拉E TLE,啥啊?
仔细一想O(10000 * 10000 * 500) = O(500,0000,0000)五百亿.....
孩子只做过矩阵加速DP,但这题不能矩阵啊.....难过的又去看了题解,真就二维树状数组啊.....
赶紧去学习了一下这是个什么高级东西,好像也不太难,就是在二维上干跟一维一样的事,
可以看出我们要快速取出dp[j][k-q]中的最大值,考虑用二维树状数组取出最大值
我们尝试改变dp数组的含义
dp[第i个拔高后的高度j][拔了k次],这样相对爽,因为这样可以直接拽出来高度对应的答案
直接把dp改为二维树状数组,dp[至多到第i个拔高后的高度j][至多拔了k次],发现爆了空间
用01背包思想去掉第一维并在dp时倒序
1 #include<bits/stdc++.h> 2 3 using namespace std ; 4 5 int a[10010],n,m,upl; 6 int dp[5510][510]; 7 8 int lowbit(int x){ 9 return x&-x; 10 } 11 12 void add(int x,int y,int a){ 13 for(int i=x;i<=upl;i+=lowbit(i)){ 14 for(int j=y;j<=m+1;j+=lowbit(j)){ 15 dp[i][j] = max(dp[i][j],a); 16 } 17 } 18 } 19 20 int ask(int x,int y){ 21 int ret = 0; 22 for(int i=x;i>=1;i-=lowbit(i)){ 23 for(int j=y;j>=1;j-=lowbit(j)){ 24 ret = max(dp[i][j],ret); 25 } 26 } 27 return ret; 28 } 29 30 int main(){ 31 ios::sync_with_stdio(false); 32 cin>>n>>m; 33 for(int i=1;i<=n;i++){ 34 cin>>a[i]; 35 upl = max(upl,a[i]); 36 } 37 upl += m; 38 int ans = 0; 39 for(int i=1;i<=n;i++){ 40 for(int k=m;k>=0;k--){ 41 int x = ask(a[i]+k,k + 1) + 1; 42 ans = max(x,ans); 43 add(a[i]+k,k+1,x); 44 } 45 } 46 cout<<ans<<endl; 47 return 0; 48 }
转载于:https://www.cnblogs.com/SINXIII/p/11269275.html
[SCOI2014]方伯伯的玉米田 //二维树状数组优化DP相关推荐
- bzoj3594 [Scoi2014]方伯伯的玉米田
题目链接 二维树状数组优化DP DP状态很容易想到:dp[i][j]表示到第i颗玉米,用了j次提升,最多保留多少: 转移: dp[i][j]=dp[k][j]+1(k<=i&&a ...
- P3287 [SCOI2014]方伯伯的玉米田
原题链接 数据结构优化DP 前置知识:二维树状数组 e.g.https://www.luogu.com.cn/problem/P4514 思路如下: 代码如下: #include <cstdio ...
- 【BZOJ3594】方伯伯的玉米田(SCOI2014)-DP+二维树状数组
测试地址:方伯伯的玉米田 做法:本题需要用到DP+二维树状数组. 首先,我们发现每次拔高的区间都是一个后缀.这个自己画一画就大概能证出来了. 那么我们就有了一个状态定义:令 f(i,j) f ( i ...
- P3287-[SCOI2014]方伯伯的玉米田【二维树状数组,dp】
正题 题目链接:https://www.luogu.com.cn/problem/P3287 题目大意 nnn个玉米高度不同,可以选择kkk个区间拔高111个高度,求最长不降子序列长度. 解题思路 显 ...
- [bzoj 3594] [Scoi2014]方伯伯的玉米田
[bzoj 3594] [Scoi2014]方伯伯的玉米田 Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美. 这排玉米一共有N株,它们的高度参差不齐. 方伯伯认为 ...
- bzoj 3594: [Scoi2014]方伯伯的玉米田
3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec Memory Limit: 128 MB Submit: 1399 Solved: 627 [Submit][ ...
- [SCOI2014]方伯伯的玉米田
题目链接 算法: 为了保证DP的正确与方便,这里先提供一个结论:每次操作都一定要拔高第n棵玉米. 以下引用NS·YJD大佬的一篇博客的证明: 首先无论操作区间在哪里,如果区间两边存在玉米,那么这些玉米 ...
- bzoj3594[Scoi2014]方伯伯的玉米田
http://www.lydsy.com/JudgeOnline/problem.php?id=3594 题目就是问你至多操作K次后的最长上升子序列. 首先,我们会得到一个结论:每次操作区间的右端点一 ...
- hdu 1892二维树状数组
这题我知道是用树状数组,可是好久没打树状数组了,就想用普通方法水过去~~结果--结果--水了好多方法都水不过,出题人真狠呐--我的水方法是对于每一次查询,初始化ans=(x2-x1+1)*(y2-y1 ...
最新文章
- python 连接数据库对中文读取超过_python 处理中文 读取数据库输出全是问号
- PHP MySQL教程期末考试题及答案,PHPMySQL答案
- Java 洛谷 P1151 子数整数
- linux编辑文本文件aa的命令,linux入门必须掌握的命令--文本文件编辑
- 在Linux 环境下搭建 JDK 和 Tomcat
- IBASE save - my toolset investigation
- 如何在 Java 中正确使用 wait, notify 和 notifyAll?
- 一些简单的前端练习demo
- Java 设计模式之构造者模式
- android访问setting权限,如何获得我的Android应用程序的可怕WRITE_SECURE_SETTINGS权限?...
- ai时代大学生的机遇和挑战_评估AI对美术的影响:威胁或机遇
- 基于微信小程序的AI智能识物
- 大数据之 Hadoop 基本概念
- 读书笔记—《雷达信号处理基础》第一章 雷达系统与信号处理概述(2)
- Codesys基础应用----ST语言实现经典冒泡排序
- LINUX系统开机后出现assuming drive cache:write through的办法
- 实验十八 CISCO设备IOS的备份与升级
- percentile_approx函数
- 转运RNA(tRNA)甲基化修饰7-甲基胞嘧啶(m7C)|tRNA-m7G
- Unity3D 2D射击小游戏瞄准线的实现
热门文章
- 用AI把自己画进动漫里,3天揽获150万+播放量,职业动画师:有被吓到
- ProgressDialog总结
- SpringMVC上下文层次结构
- 漫画|互联网人是如何一层一层甩锅的?
- C++基础编程题(50)求一元二次方程式的实根,如果方程没有实根,则输出有关警告信息。
- 消息循环中的TranslateMessage函数和DispatchMessage函数,特别注意WM_TIMER消息
- NeuroImage:通信辅助技术削弱了脑间同步?看来维系情感还得面对面互动才行...
- 用Python-turtle库作图画树
- java操作es查询数据总量
- win10系统屏幕泛白解决方案