線性DP 餅乾

2021-10-01 23:43:43 字數 1426 閱讀 6836

第一次做這種處理方法的dp,這道題我們是先在乙個大的可行方案集合中確定乙個小的子集,這個子集也滿足這個方案。我們根據排序不等式(可以自己查一下,證明過程很簡單。)可以知道,如果乙個序列式g

ig_i

gi​是公升序的。a

ia_i

ai​是降序的。那麼我們ai∗

gi

a_i*g_i

ai​∗gi

​的和一定是我們所有組合和中最小的那種。所以我們先進行排序,讓g

ig_i

gi​公升序。

然後這道題集合就是:i個小

朋友分j

個糖果的

方案的一

個集合。

i個小朋友分j個糖果的方案的乙個集合。

i個小朋友分

j個糖果

的方案的

乙個集合

。屬性就是:max

這道題的解決方案是列舉最小個數的1,因為我們知道1×權值的話是最小的。

所以我們last點就是上乙個能轉移過來1的那個j值。

所以我們轉移的時候分成兩個部分轉移,乙個是全是k個1的一坨,乙個是降序排列的一坨。

(這道題的關鍵就是看子集中1的個數)

#include

using

namespace std;

const

int n=35;

const

int m=

5005

;typedef pair<

int,

int> pii;

int f[n]

[m],ans[n]

,sum[n]

,n,m;

pii p[n]

;int

main()

sort

(p+1

,p+1

+n);

reverse

(p+1

,p+1

+n);

for(

int i=

1;i<=n;i++

) sum[i]

=sum[i-1]

+p[i]

.first;

memset

(f,0x3f

,sizeof f)

; f[0]

[0]=

0;for(

int i=

1;i<=n;i++)}

} cout<[m]

1,i=n,j=m;

while

(i&&j)

i-=k; j-

=k;break;}

}}}for

(int i=

1;i<=n;i++

) cout<<<

' ';

cout<}

AcWing 277 餅乾(線性dp)

題意 m塊餅乾,分給n個小朋友,每個小朋友至少1塊,每個小朋友有乙個數字g i 如果有x個小朋友分到的餅乾比這個小朋友多,那麼他會產生x g i 的怨氣值,你要合理分配使得所有小朋友的怨氣值之和最小,輸出最小值並輸出分配方案,如果有多種分配方案則任意輸出。思路 狀態轉移根據題意,我們知道肯定是g i...

演算法作業 求解餅乾問題 dp

題目 剛看到這道題的時候,第一時間想到的是暴力,但是發現當x位數多起來後運算量太大,遂放棄。就考慮dp來求解,不過水平有限無法發現其狀態轉移方程,就參考了一下這位老哥的解法,發現很簡單。分解餅乾問題 其主要方法就是通過不斷求模取餘數,儲存餘數的狀態,狀態轉移方程為 dp i temp n dp i ...

線性dp 區間dp

1 尼克的任務 額一道挺水的題,愣是做了幾個小時 動態規劃大致的思路還是找乙個轉移 換個詞就是影響 我們可以明顯看出本題的規則 空暇時,一遇到任務必須挑乙個接 求1 n時間內最大空暇時間 所以將任務排序是必要的,兩個關鍵字 再來想象一下當我做到第i 個任務時,我在 st i st i t i 1 時...