複製書稿 book (二分,貪心 dp)

2022-07-01 16:27:09 字數 3793 閱讀 1916

時間限制: 1 sec  記憶體限制: 128 mb

提交: 3  解決: 1

[提交][狀態][討論版][命題人:quanxing]

現在要把m本有順序的書分給k個人複製(抄寫),每乙個人的抄寫速度都一樣,一本書不允許給兩個(或以上)的人抄寫,分給每乙個人的書,必須是連續的,比如不能把第

一、第三和第四本書給同乙個人抄寫。

現在請你設計一種方案,使得複製時間最短。複製時間為抄寫頁數最多的人用去的時間。

第一行兩個整數m,k;(k≤m≤500)

第二行m個整數,第i個整數表示第i本書的頁數。

共k行,每行兩個整數,第i行表示第i個人抄寫的書的起始編號和終止編號。k行的起始編號應該從小到大排列,如果有多解,則盡可能讓前面的人少抄寫。

9 3			

1 2 3 4 5 6 7 8 9

1 5

6 78 9

一開始直接用dp,但是發現這道題具有後效性,不能有dp典型測試資料:

10 4

1 1 1 1 1 1 1 1 1 1

答案為

1 1

2 4

5 7

8 10

用dp的話答案為:

1 2

3 4

5 7

8 10

因為考慮錢4個時,dp最優就是 1 2   和3 4,但是因為k行的起始編號應該從小到大排列,如果有多解,則盡可能讓前面的人少抄寫,導致,之後發現最多為3是,為了讓1號是,1號應為1 ,第二個人幹3個

wa的錯誤解法:

#include #include 

#include

#include

#include

#include

#include

#include

#include

#define inf 0x3f3f3f3f

using

namespace

std;

int a[505

];int sum[505

];int dp[505][505

];int

main()

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

}int t=m;

int p=k;

stack

s;while(!s.empty()) s.pop();

s.push(m);

while(p!=1

) }}

s.push (1);

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

//cout

}

view code

因為書是不能排序的,所以單調處理,dp死套路:

1、問什麼設什麼:

f[i][j]表示前 i 本書分給 j 個人,

2、做過5題以上dp的小弱都應該想到,需要第三重迴圈,我設 k 用來表示*最後乙個人拿的第一本書的編號*

k列舉的範圍就是(j->i):因為前面最少要保留 j-1本書分給前面的 j-1個人,最後乙個人自己最少也要有一本,所以右邊邊界就是 i

3、到這裡已經可以把最優解(每人分到的書頁的上限)求出來,然後就懵筆了。去翻題解,原來離成功只差一步貪心。從後往前(題目說要前面的人盡可能沒那麼累),把書扔給各個人就a了。

還有一些過程中的坑,**裡面告訴你。

解法一:基本思路:dp方程求出最長花費的時間,然後用貪心的方法,從後向前遞迴,讓後面的人盡量複製多的書,再倒序輸出就可以了。

#include#include

int f[510][510];//

f[i][j] 表示把 前 i本書 分給 k 個人

int ma[510],su[510

];

intn,m;

int maxx(int x,int y)

int minn(int x,int y)

void

ff()}}

}void pr(int l,int r) //

列印當前左右邊界內的部分

ss+=ma[i];

}printf(

"%d %d\n

",1,r);//

關於第乙個人的特殊處理(邊界)

}

intmain()

ff();

//printf("%d\n",f[n][m]);

pr(1

,n);

return0;

}

view code

#include #include 

#include

#include

#include

#include

#include

#include

#include

#define inf 0x3f3f3f3f

using

namespace

std;

int a[505

];int sum[505

];int dp[505][505

];int

main()

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

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

//接下來用貪心的方法輸出

stacks;

while(!s.empty ()) s.pop();

int r=m,l=m;//

分別表示兩端點

int he=0

;

int num=0

;

for(i=m;i>=1;i--,l--)

}if(i!=0

)

}else

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

return0;

}

解法二:題解告訴我可以用二分來找最優值

#include#include

intn,m,ans;

int a[510

];

bool ch(int

x)

else

}if(an<=m) return1;

return0;

}void pr(int l,int r) //

列印當前左右邊界內的部分

ss+=a[i];

}printf(

"%d %d\n

",1,r);//

關於第乙個人的特殊處理(邊界)

}

intmain()

//二分模板

while(l<=r)

else l=mid+1

; }

//printf("%d\n",ans);

pr(1,n);//

列印函式(我用遞迴來實現的,直接倒推打迴圈也是可以的)

return0;

}

複製書稿 book 區間DP 貪心

複製書稿 book 時間限制 1 sec 記憶體限制 128 mb 題目描述 現在要把m本有順序的書分給k個人複製 抄寫 每乙個人的抄寫速度都一樣,一本書不允許給兩個 或以上 的人抄寫,分給每乙個人的書,必須是連續的,比如不能把第 一 第三和第四本書給同乙個人抄寫。現在請你設計一種方案,使得複製時間...

DP 複製書稿 book

時間限制 1000 ms 記憶體限制 65536 kb 提交數 184 通過數 78 現在要把 m本有順序的書分給 k個人複製 抄寫 每乙個人的抄寫速度都一樣,一本書不允許給兩個 或以上 的人抄寫,分給每乙個人的書,必須是連續的,比如不能把第 一 第三和第四本書給同乙個人抄寫。現在請你設計一種方案,...

二分 複製書稿

複製書稿 time limit 1000ms memory limit 65536k total submit 59 accepted 27 description 有m本書 編號為1,2,m 每本書都有乙個頁數 分別是p1,p2,pm 想將每本都複製乙份。將這m本書分給k個抄寫員 1 k m 50...