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 7sample output source232
124
456
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 二分題。原題傳送門 好吧,做這道題是為了給新手乙個教程 首先我們聊聊二分。二分利用的也是分治思想 不懂分治思想的可以看看我歸併做的那道火柴排隊。傳送門首先要了解一下二分的性質 也就是什麼題目要用二分來寫 我們假設乙個題目,如果乙個數...