某總公司擁有高效生產裝置m臺,準備分給下屬的n個分公司。各分公司若獲得這些裝置,可以為總公司提供一定的盈利。問:如何分配這m臺裝置才能使國家得到的盈利最大?求出最大盈利值。 分配原則:每個公司有權獲得任意數目的裝置,但總台數不得超過總裝置數m。其中m<=100,n<=100。
第一行為兩個整數m,n。接下來是乙個n×m的矩陣,其中矩陣的第i行的第j列的數aij表明第i個公司分配j臺機器的盈利。所有資料之間用乙個空格分隔。
只有乙個資料,為總公司分配這m臺裝置所獲得的最大盈利。
3 21 2 32 3 44
思路:二維的線性動歸,狀態轉移方程:f[i][j] = max (0<=k<=j)
(k的範圍因為題目說m臺裝置,乙個公司既可以都不擁有也可以都擁有,所以k∈[0,j])
所設變數:
int n, m;//n個分公司,m臺裝置
int a[n][n];//原始資料,a[i][j]表示第i個分公司分到j臺裝置的盈利
int f[n][n];//f[i][j] 表示前i個公司分配j個裝置的最大盈利
根據樣例,我們可以得到如下兩個**
a[m][n]陣列(注意是 mxn 大小的矩陣)12
3112
3223
4 f[m][n]陣列12
3112
3223
4 我們可以細想一下,前 i 個公司分到 j 臺裝置的最大盈利 = 前 i-1 個公司分到 k 臺裝置的最大盈利 + 第 i 個公司分到 j-k 臺裝置的盈利,
顯然是正確的,因為前 i-1 個公司分到 k 臺裝置的最大盈利並不影響後面的狀態,也就是說沒有後效性(吸取「奶牛的鍛鍊」一題的教訓)
**:
#include #include #include #include using namespace std;
const int n = 110;
int n, m;
int a[n][n];
int f[n][n];//f[i][j] 前i個公司分配j個裝置的最大盈利
void dp()
}int main()
給個複雜的測試資料:
15 10
36 67 86 8 82 88 1 96 75 82
107 68 136 105 99 104 61 176 127 133
184 120 223 179 198 134 113 247 225 205
283 136 273 217 249 140 117 312 296 205
286 207 315 306 291 224 209 346 370 272
292 279 317 332 372 227 223 375 370 295
361 327 363 373 453 277 286 410 463 316
393 413 369 387 542 302 289 419 473 393
425 443 455 407 561 358 336 477 491 445
469 521 554 478 589 440 364 572 537 512
475 534 570 520 603 530 405 574 602 593
496 542 591 547 654 587 431 587 664 637
577 632 657 645 700 635 527 620 680 680
656 643 670 670 730 715 573 676 721 707
713 719 685 685 757 770 642 744 728 745
----------------------------------------
3913
小結:一開始覺得好難,用了一維的f[n]陣列,怎麼想都覺得有後效性就放棄了,思路不對,多注意後效性問題,找準子問題,確切決策
機器分配(線性DP)
題目描述 總公司擁有高效裝置m臺,準備分給下屬的n個分公司。各分公司若獲得這些裝置,可以為國家提供一定的盈利。問 如何分配這m臺裝置才能使國家得到的盈利最大?求出最大盈利值。其中m 15,n 10。分配原則 每個公司有權獲得任意數目的裝置,但總台數不超過裝置數m。輸入格式 第一行有兩個數,第乙個數是...
線性DP之機器分配
自己瞅 懶得打了 前面是很簡單的線性dp,後面是模擬遞迴輸出方案,模擬遞迴可以設ny為機器數機器數,nx表示第nx個公司,tot為總盈利,那麼則有 a nx i dp nx 1 ny i tot 即可進行轉移,進而記錄路徑 我還記得有道題叫cd,可以看一下 includeusing namespac...
DP 機器分配
總公司擁有高效生產裝置m臺,準備分給下屬的n個公司。各分公司若獲得這些裝置,可以為國家提供一定的盈利。問 如何分配這m臺裝置才能使國家得到的盈利最大?求出最大盈利值。其中m 15,n 10。分配原則 每個公司有權獲得任意數目的裝置,但總台數不得超過總裝置數m。第一行儲存兩個數,第乙個數是裝置台數m,...