果然,直接dp不做特殊條件判定時,資料規模到一定程度時,必定超時了
看了lrc(機房某大佬)的**,if(dp[i][0]!=1&&dp[i][1]!=1) break; 依然不知是何居心,猜測可能是滿足m>1不能同時滿足那個條件吧.想不出
接著進一步分析:
受到以前有個題求序列連續和的啟發,我們可以這樣設計狀態:
令f[i][0]表示前i株花中的最後一株(不一定是i)滿足條件a時的最多剩下的株數,
f[i][1]表示前i株花作為序列終點且最後一株(不一定是i)滿足條件b時的最多剩下的株數,可以得到:
h[i]>h[i-1]時,
f[i][0]=max, f[i][1]=f[i-1][1];
h[i]==h[i-1]時,
f[i][0]=f[i-1][0],f[i][1]=f[i-1][1];
h[i]上**:
#include #include using namespace std;
const int maxn = 100010;
int h[maxn], n;
int f[maxn][2];
void init()
void work()
else if(h[i-1] > h[i]) //最後乙個比上乙個小的情況時,,更新條件b,判斷條件a的f[i-1][0]+1
else //h[i-1]==h[i],相等的情況下,無任何處理
}printf("%d", max(f[n][0], f[n][1]));
}int main()
在前面使用動態規劃的方法,並優化dp的過程之後,解決了問題。
回過頭想想,其實問題可以更簡化,思維也能更簡單清晰。
那麼問題轉化為:要怎麼才能得到乙個最長的波動鋸齒形的序列了?
觀察 5 4 3 2 1 2 事實上可以轉化為 5 1 2 ,或 2 1 2 等,即5 4 3 2多個連續遞減的點可以使用乙個點替代,
其中1是乙個轉折點,(事實上序列為了實現鋸齒形波動效果,多個連續的點都可以用乙個點替代)
那麼上面的問題就可以轉化為 "找滿足條件的轉折點個數 "
**如下:
#include#includeint high[100005]; //儲存花的高度
int main()
if(high[i]}
printf("%d\n",ans);
return 0;
}
NOIP2013提高組 花匠
花匠棟棟種了一排花,每株花都有自己的高度。花兒越長越大,也越來越擠。棟棟決定把這排中的一部分花移走,將剩下的留在原地,使得剩下的花能有空間長大,同時,棟棟希望剩下的花排列得比較別緻。具體而言,棟棟的花的高度可以看成一列整數h 1,h 2,h n。設當一部分花被移走後,剩下的花的高度依次為g 1,g ...
NOIP2013提高組 花匠
題目描述 花匠棟棟種了一排花,每株花都有自己的高度。花兒越長越大,也越來越擠。棟棟決定把這排中的一部分花移走,將剩下的留在原地,使得剩下的花能有空間長大,同時,棟棟希望剩下的花排列得比較別緻。具體而言,棟棟的花的高度可以看成一列整數h 1,h 2,h n。設當一部分花被移走後,剩下的花的高度依次為g...
NOIP 2013提高組 花匠 擺花
演算法 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 ...