單調佇列優化dp。
借鑑:首先建立方程,很容易想到的是,dp[i][j]表示第 i 個兒子身高為 j 的最低花費。分析題目很容易知道,當前兒子的身高花費只由前乙個兒子影響。因此,
dp[i][j]=min(dp[i-1][k] + abs(j-k)*c + (x[i]-j)*(x[i]-j));其中x[i]是第i個兒子原本的身高
我們分析一下複雜度。
首先有n個兒子,這需要乙個迴圈。再者,每個兒子有0到100的身高,這也需要一維。再再者,0到100的每乙個身高都可以有前一位兒子的身高0到100遞推而來。
所以樸素演算法的時間複雜度是o(n^3)。題目只給兩秒,難以接受!
分析方程:
當第 i 個兒子的身高比第 i-1 個兒子的身高要高時,
dp[i][j]=min(dp[i-1][k] + j*c-k*c + x); ( k<=j ) 其中 x=(x[i]-j)*(x[i]-j)。
當第 i 個兒子的身高比第 i-1 個兒子的身高要矮時,
dp[i][j]=min(dp[i-1][k] - j*c+k*c + x); ( k>=j )
對第乙個個方程,我們令 f[i-1][k]=dp[i-1][k]-k*c, g[i][j]=j*c+x; 於是 dp[i][j] = min (f[i-1][k])+ g[i][j]。轉化成這樣的形式,我們就可以用單調佇列進行優化了。
第二個方程同理。
以上為借鑑文章作者的思路,而我在具體實現時略有改變,即在儲存並沒有用乙個單調佇列來儲存前乙個人f[i-1][k]的解,由於只需要用到最優解,所以我直接用乙個變數min來儲存這個最優解。以下為具體實現:
#include #include #include #include #include #include #include #include #include #include #include using namespace std;
//typedef __int64 int64;
typedef long long ll;
#define m 100005
#define inf 0x3f3f3f3f
#define mod 1000000007
int dp[2][105] , n , c;
int main()
min = inf;
//比前乙個人矮
for (i = 100 ; i >= 0 ; i--)
cnt = 1-cnt;
} cnt = 1-cnt;
int ans = inf;
for (i = 0 ; i <= 100 ; i++)
ans = min(ans,dp[cnt][i]);
printf("%d\n",ans);
} return 0;
}
UESTC 我要長高
題意是 就是題目描述的那樣了吧 題意很顯而易見,一眼dp題 dp i j 代表第i個人身高為j時的最小消耗,dp i j min dp i 1 k abs j k c j h i 2 複雜度o n h i 2 很明顯有點大,學習了一下單調佇列優化dp之後,發現形如dp i min max dp j ...
uestc oj 1685 我要長高
這是一道動態規劃的dp問題 但是明顯需要o n 3 的時間複雜度 顯然需要進行優化,並且有明顯的可以進行單調佇列優化的特徵,在本次確定高度之後,總能在前一次當中尋找到乙個最優解。最優解當然是由上一次的積累量 本次積累量 其中上一次的積累量與本次的積累量之間無關聯 就是說dp i 1 k 的積累量只是...
UESTC 我要長高 DP優化
韓父有n個兒子,分別是韓一,韓二 韓n。由於韓家演技功底深厚,加上他們間的密切配合,演出獲得了巨大成功,票房甚至高達2000萬。舟子是名很有威望的公知,可是他表面上兩袖清風實則內心陰暗,看到韓家紅紅火火,嫉妒心遂起,便發微薄調侃韓二們站成一列時身高參差不齊。由於舟子的影響力,隨口一句便會造成韓家的巨...