poj 2774 木材加工 dp 二分答案 貪心

2021-07-15 09:25:14 字數 1779 閱讀 6021

poj 2774 木材加工(dp/二分答案+貪心)

time limit: 1000ms memory limit: 65536kb

description

木材廠有一些原木,現在想把這些木頭切割成一些長度相同的小段木頭,需要得到的小段的數目是給定了。當然,我們希望得到的小段越長越好,你的任務是計算能夠得到的小段木頭的最大長度。

木頭長度的單位是厘公尺。原木的長度都是正整數,我們要求切割得到的小段木頭的長度也要求是正整數。

input

第一行是兩個正整數n和k(1 ≤ n ≤ 10000, 1 ≤ k ≤ 10000),n是原木的數目,k是需要得到的小段的數目。

接下來的n行,每行有乙個1到10000之間的正整數,表示一根原木的長度。

output

輸出能夠切割得到的小段的最大長度。如果連1厘公尺長的小段都切不出來,輸出」0」。

sample input

3 7

232

124

456

sample output

source

noip 2004

這道題目在《程式設計導引》書裡標註為dp,所以所以我翻出來做了一做。

首先dp容易想到,用dp[i][j]記錄前i根木材切成j塊時候最大長度,但是時間複雜度肯定要掛,加了乙個優化,就是計算dp[i][j]時候不列舉考慮第i塊被切成1,2,…,j-1的所有情況,如果切成t塊時候l[i]/t小於了當前計算出來的dp[i][j],就不再計算t+1,t+2,…,j-1的情況了,這就是version 1。很遺憾過不了大的資料,但是相比優化之前可以額外多過一組中資料(從實際使用空間可以看出測試的是大的資料,說明中資料過了)。

後來考慮到這個題如果考慮共軛逆問題,已知長度len,求條數k,就可以貪心了,而且滿足不嚴格單調性,這恰恰可以二分答案+貪心做,就是version 2。

另外,本題不適合dp(雖然可以dp),且出處為noip2005初賽程式填空題。

version 1

time limit exceeded 64272kb 1988ms  576 b   g++
#define max_n 10000

#include

int n,k;

int l[max_n+1];

int dp[max_n+1][max_n+1];

inline

int min(int a,int b)

int main()

}printf("%d\n",dp[n][k]);

return

0; }

version 2

accepted    376kb   9ms 528 b   g++
#define max_n 10000

#define small_size 10

#include

int n,k;

int a[max_n+1];

int l=1,r=0,s=0,mid;

int f(int d)

int main()

if (s

printf("0\n");

return

0; }

while (r-l>=small_size)

for (int i=r;;i--)

if (f(i)>=k)

}

POJ 2774 字串雜湊 二分

題意 給出s,t兩個字串,求最長公共子串的長度 思路 首先二分答案x,預處理出s中長度為x的子串雜湊值並排序,在t中列舉起點,二分查詢t i.i x 的雜湊值 二分查詢直接用binary search 函式 複雜度其實是nlog方 1 include2 include3 include4 inclu...

LintCode 183 木材加工(二分查詢)

有一些原木,現在想把這些木頭切割成一些長度相同的小段木頭,需要得到的小段的數目至少為 k。當然,我們希望得到的小段越長越好,你需要計算能夠得到的小段木頭的最大長度。樣例 1 輸入 l 232 124 456 k 7輸出 114explanation 我們可以把它分成114cm的7段,而115cm不可...

木材加工(裸二分題)(附二分演算法粗略介紹)

看到旁邊的學弟也在做二分,就手賤2分鐘打了一道奇 sha 特 bi 二分題。原題傳送門 好吧,做這道題是為了給新手乙個教程 首先我們聊聊二分。二分利用的也是分治思想 不懂分治思想的可以看看我歸併做的那道火柴排隊。傳送門首先要了解一下二分的性質 也就是什麼題目要用二分來寫 我們假設乙個題目,如果乙個數...