Codevs 抄書問題1 2 3

2021-07-24 08:53:29 字數 1529 閱讀 1592

對於抄書問題1,由於標籤上寫的dp,我就寫了dp。。。。

設dp[i][j]表示前i本書由j個人抄的最小答案,則狀態轉移方程為

dp[i][j]=min,其中s為字首和,k從j-1到1列舉。

輸出方案時,由於題目要求多解時使前面的人抄的盡量少,因此可以貪心地輸出。

由於我們在前面的dp過程後已經知道了每個人抄書的頁數的最大值的最小值dp[m][k],因此可以逆序列舉第i個人,將不超過dp[m][k]的書都交給i抄,然後得出的答案保證前邊的人抄書盡可能少,這樣就能ac抄書問題1了。時間複雜度

o(k*m^2+k);

#include#define maxn 105

#define inf 0x7fffff

using namespace std;

int m,k,book[maxn],s[maxn];

struct anses;

int dp[maxn][maxn];

int main()

for(int i=2;i<=m;i++)

dp[i][j]=minx;

} }int ansxx=dp[m][k];

anses ans00[maxn];

int i=m,k0=k;

while(k0)

else if(s[i]-s[j+1]<=ansxx)

} for(int i=1;i<=k;i++)cout《但是對於抄書問題2&3,以上dp顯然不行,因此得換思路。

剛才的討論中,dp過程的作用,是求出m本書分成k份的最大代價的最小值,之後貪心地輸出就可以了,是不是有二分答案的味道?

我們可以二分查詢最大價值的最小值,然後用剛剛所得的貪心策略驗證,如果分給了》k個人,說明二分的答案偏小,反之偏大。

但是codevs的資料神坑。。。。。

由於我們剛才的貪心策略,有可能根本用不了k個人就能在最優策略下抄完m本書,此時程式將前邊的人分配了0本書!但是根據codevs上的資料,應該是每個人都至少抄一本書,呵呵。。。。

#include#define maxn 1000000+5

using namespace std;

int s[maxn],n,k,begin[maxn],end[maxn];

int main()

int lf=1,ri=s[n],ans,mid;

for(int i=1;i<=k;i++)begin[i]=end[i]=i;

while(lf>1;

int b=n,e=n,cnt=0;

while(b>=0)

if(s[e]-s[b-1]<=mid) b--;

else

} cnt++;

if(cnt>k) lf=mid+1;

else ri=mid;

} int b=n,e=n,mark=0;

for(int i=k;i>=1;i--)

b--;

} end[i]=e;

begin[i]=b+1;

e=b;

}}

codevs 3162 抄書問題

3162 抄書問題 題目描述description 現在要把m本有順序的書分給k個人複製 抄寫 每乙個人的抄寫速度都一樣,一本書不允許給兩個 或以上 的人抄寫,分給每乙個人的書,必須是連續的,比如不能把第 一 第三 第四本數給同乙個人抄寫。現在請你設計一種方案,使得複製時間最短。複製時間為抄寫頁數最...

codevs3162 抄書問題

題目描述 description 現在要把m本有順序的書分給k個人複製 抄寫 每乙個人的抄寫速度都一樣,一本書不允許給兩個 或以上 的人抄寫,分給每乙個人的書,必須是連續的,比如不能把第 一 第三 第四本數給同乙個人抄寫。現在請你設計一種方案,使得複製時間最短。複製時間為抄寫頁數最多的人用去的時間。...

codevs 3162 抄書問題

題目描述description 現在要把m本有順序的書分給k個人複製 抄寫 每乙個人的抄寫速度都一樣,一本書不允許給兩個 或以上 的人抄寫,分給每乙個人的書,必須是連續的,比如不能把第 一 第三 第四本數給同乙個人抄寫。現在請你設計一種方案,使得複製時間最短。複製時間為抄寫頁數最多的人用去的時間。輸...