校OJ 8597 石子劃分問題(dp)

2021-07-09 04:59:16 字數 1120 閱讀 8013

解題思路:

1,先將石子重量從小到大排序(從大到小也可以).

2,假設f(n,m)表示:n個石頭分成m份的最小費用. 特別的,有f(1,1)=0; f(n,1)=(an - a1)^2

那麼,除去最後乙份石頭的若干個,前面m-1份必定也是最優的分法.

若最後一堆1個石頭, f(n,m) = f(n-1,m-1)+0^2

若最後一堆2個石頭, f(n,m) = f(n-2,m-1)+(an - an-1)^2

若最後一堆3個石頭, f(n,m) = f(n-3,m-1)+(an - an-2)^2

......

最後一堆最多只能有n-m+1個石頭,因為當最後一堆為n-m+1時,前面m-1堆已經是乙個乙份了.

因此, f(n,m) = min

例如:n=5, m=2

a[1..5] = 1 3 4 8 9

f(5,2)=min=min=10

這5個石頭分2堆的最優分法:(1 3 4)(8 9)

遞推公式:
f(n,m)= f(n-k,m-1)+(a[n]-a[n-k+1])^2,n-k>=m-1,k>0
注意處理邊界問題,其中   f(n,n)=0,    f(n,1)=(a[n]-a[1])^2

例如求 n=5,m=3時,01

2345

0000

0001

0(1,1)

(2,1)

(3,1)20

(2,2)

(3,2)

(4,2)30

(5,3)

#include #include #include #include #include #include using namespace std;

#define n 1001

#define inf 10000000

int dp[n][n];

int a[n];

int n,m;

int main()

dp[i][j]=min;}}

/*for(int i=0;i<=m;i++)

{for(int j=0;j<=n;j++)

cout<

DFS 週末出遊 校OJ2348

週末天氣真好,大家組織一起出去玩 玩你妹,不好好學習 可是,有些人要知道 有好朋友了不起呀 自己最要好的朋友接受邀請了,他才會去,只有邀請到他們最好的朋友才會去 賤人就是矯情 可是作為負責人的你 冤大頭 必須判斷是否能夠辦好這次聚會 氣死爸爸拉,哼 邀請到所有的人。輸入包含多組測試資料,每組測試資料...

校oj195 雙for用contiue加速

195 給定含有n個整數的序列,要求對這個序列進行去重操作。所謂去重,是指對這個序列中每個重複出現的數,只保留該數第一次出現的位置,刪 時間限制 2 sec.記憶體限制 128 mb.試題描述 給定含有n個整數的序列,要求對這個序列進行去重操作。所謂去重,是指對這個序列中每個重複出現的數,只保留該數...

map 神奇的序列 校OJ2480

序列a如下 a 0 a a 1 b a i a pp a qq i 2,pp 向下取整 i k1 qq 向下取整 i k2 有q次詢問,每次詢問輸入pos,請輸出a pos mod。第一行輸入五個整數a,b,k1,k2,mod。第二行輸入乙個整數q。接下來q行每行輸入乙個整數pos。1 a 100 ...