poj 3042 區間dp(草的過期程度最小)

2021-07-05 08:10:50 字數 1052 閱讀 2375

題意:在一維上有n塊草坪,給出每塊草坪的位置(可以看做是x軸上的整數點),bessie初始位於l位置,他可以向左右兩個方向去吃草坪,假設吃草坪的時間不計,路上的時間是每走乙個單位,時間+1,每塊草坪都有乙個staleness值,這個值恰好等於bessie到達的時間,現在要求的是bessie將所有草坪吃完,所有草坪的staleness值之和最小。

思路:這是一道區間dp的問題,我們用dp[i][j][0]表示從i-j區間都吃完,最後停留在i位置,所有草坪的最小的staleness值;dp[i][j][1]表示i-j區間都吃完,最後停留在j位置,所有草坪的最小的staleness值。(顯然i~j都吃完之後不可能停在中間。因為如果i、j都吃完了,那麼從i到j或者從j到i必然經過了中間的所有點)。那麼這兩個狀態的轉移方程就是:

dp[i][j][0] = min(dp[i+1][j][0]+(s[i+1]-s[i])*k , dp[i+1][j][1]+(s[j]-s[i])*k);//k是剩下多少草沒吃,它們的staleness值要增加,而s[i+1]-s[i]之類的是最後一段行走的距離,也即增加量。

dp[i][j][1] = min(dp[i][j-1][0]+(s[j]-s[i])*k , dp[i][j-1][1]+(s[j]-s[j-1])*k);

其中k = n-(j-i);

注意把起始點也新增進了草點,這樣便於計算。

注意計算順序,這樣的計算順序才能保證方程中的式子已經先被計算出來了。

#include #include #include #include #include #include using namespace std;

#define inf 0x3fffffff

#define clr(s,t) memset(s,t,sizeof(s))

#define n 1005

int dp[n][n][2],s[n];

int n,b;

int main()

}printf("%d\n",min(dp[1][n][0],dp[1][n][1]));

return 0;

}

POJ 3042 區間dp 左端點右端點01

題意 在一維座標系下,給定n個草坪的座標 1 n 1000 再給定起點l 1 l 1e6 每個草坪有乙個staleness值,初始化為0。每次走一格,所有的staleness值 1,並且要從起點遍歷每乙個草坪,求staleness值的最小值。離散化處理n個點 dp i j 0 區間 i,j 已經遍歷...

poj1651 區間DP 基礎

題意 給你一串數字,頭尾不能動,每次取出乙個數字,這個數字貢獻 該數字與左右相鄰數字的乘積,求乙個最小值。思路 用dp s t 去代表s到t的最小值,包括a s 和a t 然後從區間為3開始列舉,對每個小區間列舉乙個取出的數,狀態轉移方程就是 dp s t min dp s k dp k j a i...

poj 1141 區間dp 列印路徑

題意 定義合法的括號序列如下 1 空序列是乙個合法的序列 2 如果s是合法的序列,則 s 和 s 也是合法的序列 3 如果a和b是合法的序列,則ab也是合法的序列 例如 下面的都是合法的括號序列 下面的都是非法的括號序列 給定乙個由 和 組成的序列,找出以該序列為子串行的最短合法序列。解題思路 這題...