書的複製【動態規劃】
time limit:10000ms memory limit:65536k
description
現在要把m本有順序的書分給k個人複製(抄寫),每乙個人的抄寫速度都一樣,一本書不允許給兩個(或以上)的人抄寫,分給每乙個人的書,必須是連續的,比如不能把第
一、第三、第四本書給同乙個人抄寫。
現在請你設計一種方案,使得複製時間最短。複製時間為抄寫頁數最多的人用去的時間。
input
第一行兩個整數m,k;(k≤m≤500)
第二行m個整數,第i個整數表示第i本書的頁數。
output
共k行,每行兩個整數,第i行表示第i個人抄寫的書的起始編號和終止編號。k行的起始編號應該從小到大排列,如果有多解,則盡可能讓前面的人少抄寫。
sample input
9 31 2 3 4 5 6 7 8 9
sample output
1 5
6 7
8 9
這一題可以用dp解決,不過dp不是最優的方法,如果不是為了看四邊形不等式的,可以另找題解。
這題和郵局(一樣是一道區間dp,容易寫出狀態轉移方程f[i][j]=min},其中f[i][j]表示前i本書由j個人抄寫的最短時間,sum表示字首和,sum[i]表示前i本書的總頁數。
四邊形不等式的優化在郵局post office講過一遍,這題的決策變數顯然也是符合區間單調性的
。嗯……真的沒什麼好說的,這題和郵局的型別一模一樣。
不過最後輸出的不是最優解,而是方案,就不是dp解決的了。dp求出的是最優解,方案其實從s[m][n]回溯也是可以求的。但多個最優解方案時讓前面的人盡量少抄這個條件就比較難處理了,我用s[m][n]回溯的方法調了很久,還是沒調出來,所以就用了另乙個思路:貪心。
倒著列舉,只要後面的人還能抄就盡量讓他多抄些,直到不能抄(設他當前抄的是i至l(i<=l)段且符合要求,則i--;直到sum[l]-sum[i-1]>最優解f[m][n],那麼說明他最多可以抄i+1到l段)。
解釋得不太好……看看**吧:(注釋不打了,對照郵局post office,dp過程是幾乎一樣的)
#include#include#includeusing namespace std;
int m,n;
int a[501];
int ans[501][2];
int f[501][501];
int s[501][501];
int main()
for (int i=1;i<=m;i++)
int inf=2147483647;
for (int j=2;j<=n;j++)
}} int last=m;
int tot=0;
for (int i=m;i>=1;i--)
if (a[last]-a[i-1]>f[m][n])
printf("%d %d\n",1,last);
for (int i=tot;i>=1;i--)
printf("%d %d\n",ans[i][0],ans[i][1]);
return 0;
}
動態規劃專題 解題報告 A
乙個經典的貨郎擔問題,加上17的範圍限制各種明示狀態壓縮,用二進位制來表示走過哪幾個城市,我們可以開乙個二維陣列dp i j 表示走過了i的城市,最後在j城市停留的距離。預處理一遍每個城市間的距離,算出dis i j 到dp i j 的狀態可以由 1 1 j k 轉移過來,比較距離儲存最優值就行,然...
解題報告 hdoj1069(動態規劃)
大概題意 猴子想拿到房頂的香蕉,有幾種不同的block可用,每種可用若干個,每種block有三個引數 x,y,z。猴子可以將面積大的放下層,然後再放上乙個面積小的,然後 這樣可以增加最後能達到的高度。但是有個要求 上面的block的長和寬都必須嚴格的小於下面的block。每個block的兩個引數當做...
動態規劃 hdoj 1087解題報告
hdoj 1087 super jumping jumping jumping 題意大致是求乙個數列的單調遞增子列的和的最大值。資料只有1000,因此隨便dp一下就好。思路 令b 1,n 為數列,a i 為以b i 為最後一項的和最大的子串行。因此有遞推公式 a 0 0 a i max a j b ...