首页 > 其他分享 >luoguP3287 [SCOI2014] 方伯伯的玉米田

luoguP3287 [SCOI2014] 方伯伯的玉米田

时间:2023-11-15 18:45:20浏览次数:47  
标签:方程 拔高 一个 玉米 玉米田 luoguP3287 维护 SCOI2014 转移

题目描述

方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美。这排玉米一共有 NN 株,它们的高度参差不齐。方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感的玉米拔除掉,使得剩下的玉米的高度构成一个单调不下降序列。方伯伯可以选择一个区间,把这个区间的玉米全部拔高 11 单位高度,他可以进行最多 KK 次这样的操作。拔玉米则可以随意选择一个集合的玉米拔掉。问能最多剩多少株玉米,来构成一排美丽的玉米。

输入格式

第一行包含两个整数 n,Kn,K,分别表示这排玉米的数目以及最多可进行多少次操作。第二行包含 nn 个整数,第 ii 个数表示这排玉米,从左到右第 ii 株玉米的高度 aiai​。

输出格式

输出一个整数,最多剩下的玉米数。

输入输出样例

输入 #1
3 1
2 1 3
输出 #1
3

说明/提示

100%100% 的数据满足:2≤N<1042≤N<104,2≤K≤5002≤K≤500,1≤ai≤50001≤ai​≤5000。

 

题面简洁得不像是noip的题。。
我自己第一次想的时候弄错了一个点,题面里说拔高的起点和终点都由我们决定,但是事实上,终点可以锁死是n,这个是可以证明绝对不亏的
但是我没想到。。。
然后就没有思路了

我以前明明做过这种可以拔高的lis的题面的啊,为什么这次想不到?
太奇怪了
那状态就很明显了
f[i][k]表示已经拔高了k次,每次的起点不超过i的时候以a[i]结尾的子串最长有多长

对于每一个不满足不下降条件的a[i],我们有两个转移,一个是不提高直接拔掉,一个是提高,答案++,k+=一个数字
用从后向前的转移,对于每一个f[i][j],枚举所有1<=k<=i,然后再枚举所有的1<=h<=j,来进行不拔高的转移和拔高的转移
但是这个条件限制的也太多了点吧。。。
这怎么维护啊
emmmmm
好像直接一个前缀和类似的求最大值就好了?
我想想看
好像没问题啊,我试试看
怎么可能这么简单。。
我的转移方程是有条件的,拔高的次数是由转移的位置和当前位置共同决定的
又有二位偏序的味道了
但是是三维的啊
还有一个k的要求
可以做到吗?
想想看
要把方程写下来,不然不好想
果然,写下来方程之后清晰多了。。
dp方程还是要写出来的,特别是优化。。。
没有方程什么都没有
我想把式子写上来。。。但是我真的是不会用typora啊啊啊啊啊啊啊
我学学看吧,能把这个思考过程写上来,对我的以后的帮助真的很大,可以帮助我快速思考和确定思路
好像是只要单个变量的值都可以维护啊
确实哎,这好像又是一种新的维护了
在还没有使用二位偏序的时候,我们可以暂时用一个log的复杂度为代价来直接无视一个转移范围限制条件
这个被无视的条件在代码里面的反映就是使用树状数组的二位偏序啊
卧槽可以的

好好好,这道紫题写的我好爽啊,刚刚好是那种我垫垫脚能够到的难度,收获很大


错了,方程都是有问题的。。
好难啊,md
dp的转移方程似乎是倾向于把范围扩大,因为维护一个区间所有数值的信息其实比维护更多个更小范围的区间的信息更加方便
唉,我的理解还是有不小的偏差的。。
再写一题吧
说说我看完博客之后的思路
其实三个条件,我们就是直接二维树状数组就好了
其中一个条件是因为阶段的划分而天然满足的

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read() {
    char c=getchar();int a=0,b=1;
    for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
    for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b;
}
inline int lowbit(int x)
{
    return x&(-x);
}
int n,k,a[10001],tr[6001][501],tot1,tot2,ans,mx;
void add(int x,int i,int y)
{
    for(;x<=mx+k;x+=lowbit(x))
        for(int j=y;j<=k+1;j+=lowbit(j))
            tr[x][j]=max(tr[x][j],i);
}
inline int ask(int x,int y)
{
    int ans=0;
    for(;x;x-=lowbit(x))
        for(int i=y;i;i-=lowbit(i))
            ans=max(ans,tr[x][i]);
    return ans;
}
int main()
{
    n=read(),k=read();
    for(int i=1;i<=n;i++)
    {
        a[i]=read();
        mx=max(mx,a[i]);
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=k;j>=0;j--)
        {
            int x=ask(a[i]+j,j+1)+1;
            ans=max(ans,x);
            add(a[i]+j,x,j+1);
        }
    }
    cout<<ans<<endl;
    return 0;
}
//2 1 1 2

我其实不是很明白,就是添加的和转移的式子为什么是一样的
倒序的循环很好理解,防止一个点被转移两次

他们的方程思路和我的一模一样,但是表述不是很严谨,利用了贪心的思路扩大的枚举的范围,更加方便维护了
草,方程错了

两个点
1.方程的内部尽量简洁,条件往外面写
2.利用贪心扩大范围,有的时候可能会更好维护
这题要是把范围写的太死。。就好难搞了

标签:方程,拔高,一个,玉米,玉米田,luoguP3287,维护,SCOI2014,转移
From: https://www.cnblogs.com/HLZZPawa/p/17830157.html

相关文章

  • P3287 [SCOI2014] 方伯伯的玉米田
    首先每次选择的区间结尾都可以换成\(n\),仍然保持单调不降,我们就按这个策略拔高玉米。令\(f_{i,j}\)表示\(1\simi\)这段前缀进行了\(j\)次操作,第\(i\)株玉米不被拔掉,所能剩下最多的玉米数量:\[f_{i,j}=\max\{f_{p,q}|p<i,q<j,a_p+q\leqa_i+j\}+1\]枚举\(i\),剩下两个......
  • [SCOI2014] 方伯伯的OJ 解题报告
    已经不记得平衡树的样子了。Statement给定一个\(1\simn\)的序列,你有如下几个操作:改变一个人的编号将一个人放在序列开头将一个人放在序列结尾查询排名为\(k\)......
  • [SCOI2014]方伯伯的玉米田题解
    [SCOI2014]方伯伯的玉米田题目描述方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美。这排玉米一共有\(N\)株,它们的高度参差不齐。方伯伯认为单调不下降序......
  • Luogu P3286 [SCOI2014]方伯伯的商场之旅
    题意方伯伯有一天去参加一个商场举办的游戏。商场派了一些工作人员排成一行。每个人面前有几堆石子。说来也巧,位置在\(i\)的人面前的第\(j\)堆的石子的数量,刚好是\(......
  • P3287 [SCOI2014]方伯伯的玉米田
    \(\mathcal{Link}\)显然,每次区间加的一定是一段后缀。设\(f(i,j)\)表示必选第\(i\)个位置用了\(j\)次的最大保留值。\[f(i,j)=\max\{f(k,l)\}(k\leqi,l\leqj,a......
  • P3287 [SCOI2014]方伯伯的玉米田
    题意进行最多\(k\)次区间\(+1\)操作,使得序列中的最长不下降子序列最长。分析首先,拔高的区间一定是\([i,n]\)这种的,因为拔高一段区间,对于区间内部的相对高度是不变......
  • BZOJ 4810([Ynoi2017]由乃的玉米田-莫队)
    Description由乃在自己的农田边散步,她突然发现田里的一排玉米非常的不美。这排玉米一共有N株,它们的高度参差不齐。由乃认为玉米田不美,所以她决定出个数据结构题这个题是这......
  • P3285 [SCOI2014]方伯伯的OJ
    P3285SCOI2014方伯伯的OJSplay+将一个区间合并为一个点,类似P3960NOIP07列队用STL的map存被合并区间的右端点对应的节点下标,查询节点下标时lower_bound即可点击查......
  • 玉米田
    玉米田农夫约翰的土地由$M\timesN$个小方格组成,现在他要在土地里种植玉米。非常遗憾,部分土地是不育的,无法种植。而且,相邻的土地不能同时种植玉米,也就是说种植玉米的......