jzoj3521 道路覆蓋 二分 狀壓dp

2021-08-29 14:01:33 字數 1362 閱讀 5522

description

ar把一段凹凸不平的路分成了高度不同的n段,並用h[i]表示第i段高度。現在tar一共有n種泥土可用,它們都能覆蓋給定的連續的k個部分。

對於第i種泥土,它的**為c[i],可以使得區間[i,min(n,i+k-1)] 的路段的高度增加e[i]。

tar要設定一種泥土使用計畫,使得使用若干泥土後,這條路最低的高度盡量高,並且這個計畫必須滿足以下兩點要求:

(1)每種泥土只能使用一次。

(2)泥土使用成本必須小於等於m。

請求出這個最低的高度最高是多少。

input

第一行為如上文所示的三個正整數:n,m,k。

接下來n行,每行3個如上文所示的正整數h[i],e[i],c[i]。

output

輸出有且只有乙個數字,為最底部分的高度的最大值

sample input

4 20 1

1 3 5

1 7 3

4 6 9

3 5 13

sample output

3data constraint

對於30%的資料:n≤20。

對於100%的資料:1≤k≤11,1≤n≤100,0≤m,h[i],e[i],c[i]≤1000000。

分析:二分列舉最低的高度,接下來考慮判斷合法性:設f[i][j]表示在前i位完成j狀態的最小金錢代價,那麼只要存在狀態x使得f[n][x]≤m。然後再考慮狀態的轉移:注意對於一位i只由它的前k位得到,那麼就是說f[i][j]由它的前k位得到,所以j只有k位。k的範圍是極小的所以不會超時;要使列舉的最小高度l合法,還要滿足該點決策完成之後的高度≥l。然後我們就可以根據條件來進行狀態轉移:

f[i+1][不選的狀態j]=minx(f[i+1][j>>1],f[i][j]); 且要滿足最小高度為x //該位不選

f[i+1][選之後的狀態j]=minx(f[i+1][(j>>1)|(1<<(k-1))],f[i][j]+c[i+1]); 滿足「最小高度」為x //該位選

**

#include #include #include #define n 105

#define inf 1e9

using namespace std;

int n,m,k,ans;

int f[n][1<<12],h[n],c[n],e[n];

int fmin(int x, int y)

for (int i = 0; i < (1 << k); i++)

if (f[n][i] <= m) return true;

return false;

}int main()

printf("%d", ans);

}

jzoj 3521 道路覆蓋 cover

link description tar把一段凹凸不平的路分成了高度不同的n段,並用h i 表示第i段高度。現在tar一共有n種泥土可用,它們都能覆蓋給定的連續的k個部分。對於第i種泥土,它的 為c i 可以使得區間 i,min n,i k 1 的路段的高度增加e i tar要設定一種泥土使用計畫,...

JZOJ 二分 抄書

與書的複製差不多 洛谷 書的複製 但是只要輸出最大的時間 樣例輸入9 3 100 200 300 400 500 600 700 800 900樣例輸出1700樣例解釋1 1500 100 200 300 400 500 2 1300 600 700 3 1700 800 900 1300 1500...

二分 抄書 (jzoj 2123)

有n本書,分給m個人抄,每個人只能拿到連續的書 不能把一本書分開 問抄書最多的人要抄多少頁9 3 100 200 300 400 500 600 700 800 9001700對於10 的資料,有n 10 對於50 的資料,有n 500 對於100 的資料,有n 3000 這道題很可能想到dp但會炸...