标签:Noip2013 int read Rg Luogu1970 go include dp define
$Sol$
和$Poj1037\ A\ Decorative\ Fence$好像吖.
$f[i][0/1]$表示前$i$个数,且选了第$i$个数,这个数相对于上一个数是下降(上升)的,这样的序列的最大长度.
$f[i][0]=max(f[k][1])+1,k<i且h[k]>h[i]$
$f[i][1]=max(f[k][0])+1,k<i且h[k]>h[i]$
最后答案就是$max_{i=1}^{n}f[i][0/1]$.
然而这样的复杂度是$O(N^2/2)$的,不能$AC$,优化很容易想到能不能去掉内层循环,通过某个变量维护或者是$f[i][0/1]$直接由$f[i-1][0/1]$推出.前者似乎是不可行的,考虑后者.将$f[i][0]$的意思改成前$i$个数选了若干数,最后一个数相对于倒数第二个数是递减的序列的最长长度,$f[i][1]$类似.然而我根本就想不到转移方程于是打开$TJ....ovo$
$if(h[i]>h[i-1])f[i][1]=f[i-1][0]+1;else f[i][1]=f[i-1][1];$
$if(h[i]<h[i-1])f[i][0]=f[i-1][1]+1;else f[i][0]=f[i-1][0];$
最后答案是$f[n][0/1].$
这样理解叭,对于当前序列,假如最后一个数是波谷,那么我们是希望这个数越小越好的,因为后面的波峰更有选择余地.
$Code$
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<algorithm> #define il inline #define Rg register #define go(i,a,b) for(Rg int i=a;i<=b;++i) #define yes(i,a,b) for(Rg int i=a;i>=b;--i) #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long #define db double #define inf 2147483647 using namespace std; il int read() { Rg int x=0,y=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();} while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();} return x*y; } const int N=100010; int n,h[N]; ll f[N][2]; il ll Max(ll x,ll y){return x>y?x:y;} int main() { n=read();go(i,1,n)h[i]=read(); f[1][0]=f[1][1]=1; go(i,2,n) { if(h[i]>h[i-1])f[i][1]=f[i-1][0]+1; else f[i][1]=f[i-1][1]; if(h[i]<h[i-1])f[i][0]=f[i-1][1]+1; else f[i][0]=f[i-1][0]; } printf("%lld\n",max(f[n][0],f[n][1])); return 0; }View Code
标签:Noip2013,int,read,Rg,Luogu1970,go,include,dp,define 来源: https://www.cnblogs.com/forward777/p/11410363.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。