題意是……就是題目描述的那樣了吧 題意很顯而易見,一眼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]) + x[i]的方程,一般可以用單調佇列優化。
然後我們試著把方程變形一下
當第i個人身高比前乙個高的時候
dp[i][j] = min( dp[i-1][k] - k * c + j * c + (j - h[i]) ^ 2 ) (1 <= k <= j)
那麼令f[i-1][k] = dp[i-1][k] - k * c , x[i][j] = j * c + (j - h[i]) ^ 2 (先忽略i這個變數),則原方程可以看成dp[j] = min(f[k]) + x[j] ,因此可以用單調佇列來優化,不過這裡的k取值範圍是(1, j) ,所以即使不用單調佇列也是可以的,直接令f[i][j] 為 min(dp[i][k] - k * c) 直接遞推就行
當第i個人身高比前乙個矮的時候同理。令f[i][j]為j到100裡面dp[i][k] + k * c的最小值,倒著遞推即可。
但是有時候如果對k的取值範圍有所限制,(比如限定某一固定長度的區間時)就需要用到單調佇列了。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
#define long long long
const
int inf=0x3f3f3f3f;
const
int mod=1e9+ 7;
const
double pi=acos(-1.0);
#define clri(x) memset(x,-1,sizeof(x))
#define clr0(x) memset(x,0,sizeof x)
#define clr1(x) memset(x,inf,sizeof x)
#define clr2(x) memset(x,-inf,sizeof x)
#define eps 1e-10
#define lson l , mid , rt<< 1
#define rson mid + 1 ,r , (rt<<1)+1
#define root 1, m , 1
int dp[2][110] ;
int h[51000] ;
int f[2][110] ;
int f2[2][110] ;
int main()
int ans = inf ;
for(int i = h[n] ; i <= 100 ; ++ i)ans = min(ans , dp[pre][i]) ;
printf("%d\n",ans) ;
}}
UESTC 1685 我要長高
單調佇列優化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個兒子原本的身高 我們分...
UESTC 我要長高 DP優化
韓父有n個兒子,分別是韓一,韓二 韓n。由於韓家演技功底深厚,加上他們間的密切配合,演出獲得了巨大成功,票房甚至高達2000萬。舟子是名很有威望的公知,可是他表面上兩袖清風實則內心陰暗,看到韓家紅紅火火,嫉妒心遂起,便發微薄調侃韓二們站成一列時身高參差不齊。由於舟子的影響力,隨口一句便會造成韓家的巨...
UESTC 594 我要長高
我要長高 設 dp i j 表示到第 i 個人,他的身高是 j 的時候的最小損失,然後得到乙個樸素的轉移方程 dp i j min dp i 1 k abs k j c j a i 2 把無關的丟到 min 外面來 dp i j left min dp i 1 k k c j c j a i 2 j...