大多數人的錯誤原因:盡可能讓前面的人少抄寫,如果前幾個人可以不寫則不寫,對應的人輸出0 0。
不過,已經修改資料,保證每個人都有活可幹。
現在要把m本有順序的書分給k給人複製(抄寫),每乙個人的抄寫速度都一樣,一本書不允許給兩個(或以上)的人抄寫,分給每乙個人的書,必須是連續的,比如不能把第
一、第三、第四本書給同乙個人抄寫。
現在請你設計一種方案,使得複製時間最短。複製時間為抄寫頁數最多的人用去的時間。
輸入格式:
第一行兩個整數m,k;(k≤m≤500)
第二行m個整數,第i個整數表示第i本書的頁數。
輸出格式:
共k行,每行兩個整數,第i行表示第i個人抄寫的書的起始編號和終止編號。k行的起始編號應該從小到大排列,如果有多解,則盡可能讓前面的人少抄寫。
輸入樣例#1:
9 3輸出樣例#1:1 2 3 4 5 6 7 8 9
1 5這道題可以用dp解決,但是二分+貪心也是一種非常不錯的解法。6 78 9
我在這裡談一談後者。
通常,當我們看到題目要求***xx的最大值最小是多少,又或者是******的最小值最大是多少,這道題十有**要用二分了。用二分發能在o(nlogn)的複雜度裡列舉可能的答案,再寫乙個判斷函式去判斷二分出的值的大小。
值得注意的是,運用二分法的時候,答案一定要滿足單調性,不然無法二分。
書的複製這道題,我們可以二分出每個人抄寫的時間。然後從最後乙個人開始列舉(題目中要求前面的人盡量抄寫的少),用貪心的思想記錄下每個人能夠複製的書。如果所有書能夠抄完,說明二分出的時間》=最小時間,如果不能,說明二分出的時間<=最小時間,就再次進行二分。
二分最終得出的值就是正確答案了,從前往後輸出即可。
#include#include#include#includeusing namespace std;
int a[10001],k,m,sum=0,l[10001],r[10001];//ai表示編號為i的書的頁數
bool check(int x)//二分判斷答案正確性,這裡我是在判斷完正確答案之後再貪心求出答案。
else
}if(book==0)
return 0;
else
return 1;
}int main()
int l=sum/k,r=sum;
while(l>1;
if(check(mid))
l=mid+1;
else
r=mid;
} int t=l,book=m;
for(int i=k;i>=1;i--)
l[i]=book+1;
} for(int i=1;i<=k;i++)
cout
}
dp 洛谷P1281 書的複製
本來以為水題,後來炸了 dp方程這個直接想總不難把 毫無優化的暴力轉移 但是最後輸出方案的時候,不可以按照dp的方案輸出的 因為dp它的方案是讓子節點數值最優 這樣的方案是是不可以保證總的方案最優的 所以要最後貪心輸出答案 就是後面的人經可能的取 include define ll long lon...
P1281 書的複製
先說下題意吧,題面給的題意我都看不懂 有 n 本書,每本書有乙個頁數 a i 每個人能寫連續的幾本書,他們寫書的速度可以認為是1頁1天。求讓 k 個人抄完這 n 本書的最短時間。ps k 個人抄書的時間是其中抄的最慢的人用的時間。dp的狀態非常容易想 dp i j 表示前 i 本書,用 j 個人抄的...
P1281 書的複製 DP
原題鏈結 和之前的統計單詞個數十分類似 將前面的分為兩部分 一部分是前面的人抄的 剩下的是自己抄的 取max 和原時間取min include include include include include include include include include include includ...