動態規劃,dp優化處理 人數計數問題

2021-10-06 01:47:29 字數 1278 閱讀 6845

題面:

東東每個學期都會去寢室接受掃樓的任務,並清點每個寢室的人數。每個寢室裡面有ai個人(1<=i<=n)。從第i到第j個宿舍一共有sum(i,j)=a[i]+…+a[j]個人。東東需要掃樓m次,每一次數第i到第j個宿舍sum(i,j)

問題是要找到sum(i1, j1) + … + sum(im,jm)的最大值。且ix <= iy <=jx和ix <= jy <=jx的情況是不被允許的。也就是說m段都不能相交

注:1 ≤ i ≤ n ≤ 1e6 , -32768 ≤ ai ≤ 32767人數可以為負數(1<=n<=1000000)

輸入m,輸入n。後面跟著輸入n個ai

輸出最大和

sample input:

1 3 1 2 3

2 6 -1 4 -2 3 -2 3

sample output:68

注意:資料量很大,需要scanf讀入和dp處理

思路:利用動態規劃的思想,因為要求m個子段都不能相交,所以可以利用狀態轉移方程dp[i][j] = max(dp[i][j-1]+a[j] , dp[i-1][k]+a[j])來計算,dp[i][j]必須取到第j個元素,否則這種情況就肯定會在其他情況中被列舉過。前乙個狀態表示將a[j]加入dp子串,後一種表示單獨將a[j]作為乙個子串

這樣做的話需要三個迴圈,由於本題的資料量很大,這樣做會爆掉。

觀察轉移方程發現,其實每次狀態轉移後的結果是上一次比較中較大的值加上a[j],所以可以建立乙個陣列premax對於從 j 個元素中尋找 i-1 段中的最大值,dp記錄從 j 個元素中找 i 段的最大子串和

同時可以將dp降為一維滾動陣列形式,這樣的話轉移方程就變成了dp[j]=max(dp[j-1]+a[j],premax[j-1]+a[j])

#include

#include

#include

#include

#include

using

namespace std;

const

int n=

1e6+1;

const

int inf=

1e9+1;

int ans=

-inf;

int a[n]

;int dp[n]

;int premax[n]

;int

main()

} cout<}return0;

}

動態規劃 計數類DP

計數類dp狀態函式的值是集合中元素的個數 1.例題 整數劃分 乙個正整數n可以表示成若干個正整數之和,形如 n n1 n2 nk,其中n1 n2 nk,k 1。我們將這樣的一種表示稱為正整數n的一種劃分。現在給定乙個正整數n,請你求出n共有多少種不同的劃分方法。輸入格式 共一行,包含乙個整數n。輸出...

動態規劃 區間DP 計數類DP

acwing 282.石子合併 區間dp的特點是狀態表示的時候表示的是某乙個區間的情況 動態規劃模型分析 即 不管石子如何合併,最後一步的操作一定是將兩堆石子合併 把步驟回到倒數第一步。當在做最後一次操作時遍歷所有區間,將最後一步最小的情況記錄進f陣列裡 部分如下 全域性變數 const int n...

動態規劃 單調斜率優化DP

acwing 1087.修剪草坪 旅行商問題 輸入樣例 641 351 23 輸出樣例 acwing 1087.修剪草坪 動態規劃 f i max f i 1 f i j 1 sum i j sum i f i 表示從前i個中選,且合法的方案數。令x i j,則有 f i min f i 1 f x...