【演算法】dp||貪心
【題解】
(1)動態規劃:
令f[i][0..1]為兩種條件下前i株花的最大保留數量,狀態轉移方程:
f[i][0]=max(f[j][1]+1) (j=i-1...1)(h[i]>h[j])
f[i][1]=max(f[j][0]+1) (j=i-1...1)(h[i]初始化:f[i][0]=f[i][1]=1,這樣時間複雜度是o(n^2)。
由於題目的資料範圍中有一句話:所有的h_i隨機生成,所有隨機數服從某區間內的均勻分布。
所以加個優化,因為f[i][0](i=1...n)和f[i][1](i=1...n)存在單調性(不下降),即f[x][0]>=f[y][0](x>y),f[x][1]>=f[y][1](x>y)
所以在狀態轉移列舉j時,當f[i][0]和f[i][1]都》1(大於初始值)時,就可以不用再向前找j而是直接跳向下乙個i。
優化後可以通過所有資料(ac)。
#include#includeview codeusing
namespace
std;
const
int maxn=100010
;int f[maxn][2
],h[maxn],n;
intmain()
for(int i=2;i<=n;i++)
for(int j=i-1;j>=1;j--)
printf("%d
",max(f[n][0],f[n][1
]));
return0;
}
(2)貪心
學自:先把序列中相鄰的相同元素刪剩乙個(去重),然後在序列中尋找所有滿足a[i-1]a[i+1]或者a[i-1]>a[i]解釋:去重後的序列就是在不斷波動,因此這兩種元素一定會交替出現,而相鄰的這兩種元素中間的一段,這一段必然是單調遞增或者單調遞減的,因此最多選擇兩個元素,而選擇兩個端點就必然是最優的。
這樣時間複雜度是o(n)。
#includeint a[100010],b[100010view code],n,ans,tot;
intmain()
NOIP2013提高組 花匠
花匠棟棟種了一排花,每株花都有自己的高度。花兒越長越大,也越來越擠。棟棟決定把這排中的一部分花移走,將剩下的留在原地,使得剩下的花能有空間長大,同時,棟棟希望剩下的花排列得比較別緻。具體而言,棟棟的花的高度可以看成一列整數h 1,h 2,h n。設當一部分花被移走後,剩下的花的高度依次為g 1,g ...
NOIP2013提高組 花匠
題目描述 花匠棟棟種了一排花,每株花都有自己的高度。花兒越長越大,也越來越擠。棟棟決定把這排中的一部分花移走,將剩下的留在原地,使得剩下的花能有空間長大,同時,棟棟希望剩下的花排列得比較別緻。具體而言,棟棟的花的高度可以看成一列整數h 1,h 2,h n。設當一部分花被移走後,剩下的花的高度依次為g...
Noip2013提高組day2 花匠
我們把原序列大概抽象在函式圖上,就會得出這樣的結果 如下圖 顯然,圈出來的點就是我們要保留的,不可能存在刪掉一大段會存在更優的情況。做法就是每次順著找乙個最高的點,再找乙個最低的點,如果存在相同的則視為乙個點。include include include define fo i,j,k for i...