UESTC 我要長高

2021-07-31 20:13:01 字數 1713 閱讀 4784

題意是……就是題目描述的那樣了吧 題意很顯而易見,一眼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...