AcWing 277 餅乾(線性dp)

2021-10-06 18:50:08 字數 2350 閱讀 4023

題意:m塊餅乾,分給n個小朋友,每個小朋友至少1塊,每個小朋友有乙個數字g[i],如果有x個小朋友分到的餅乾比這個小朋友多,那麼他會產生x*g[i]的怨氣值,你要合理分配使得所有小朋友的怨氣值之和最小,輸出最小值並輸出分配方案,如果有多種分配方案則任意輸出。

思路:狀態轉移根據題意,我們知道肯定是g[i]越大的小朋友得到的餅乾越多,因為相同的劃分方案,餅乾多的那份給g[i]大的要比給g[i]小的產生的怨氣值要小。所以我們先貪心,讓每個小朋友按照g[i]的從大到小排序。然後我們用f[i][j]表示j塊餅乾分給i個小朋友所得到的最小怨氣值,然後我們f[i][j]是由f[i][j-i]轉化而來(給j-i塊分給i個人的基礎上每人再分一塊),然後我們列舉一下這i個人的中有k個人是只拿了1塊的,此時產生的怨氣值就是f[i-k][j-k]+(g[i-k+1]+g[i-k+2]+…+g[i]) * (i-k),所以我們可以先處理字首和來簡化計算,f[i-k][j-k]+(s[i]-s[i-k]) * (i-k),最後f[n][m]就是答案。

思路:路徑輸出這題還要求我們把每個人分得多少餅乾輸出,其實也就是狀態轉移的逆過程。如果f[i][j]==f[i][j-i],說明是直接這i個人都加1塊,否則就列舉k,即由加上k個1轉化而來,並且根據貪心的規則將靠後的k個賦值為(1+之前參與共同加1的個數)

**:

#include

#define endl '\n'

#define null null

#define ls p<<1

#define rs p<<1|1

#define fi first

#define se second

#define mp make_pair

#define pb push_back

#define ll long long

//#define int long long

#define pii pair

#define ull unsigned long long

#define all(x) x.begin(),x.end()

#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

#define ct cerr<<"time elapsed:"<<1.0*clock()/clocks_per_sec<<"s.\n";

char

*fs,

*ft,buf[

1<<20]

;#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;

inline

intread()

while

(ch>=

'0'&&ch<=

'9')

return x*f;

}using

namespace std;

const

int n=

1e3+5;

const

int inf=

0x3f3f3f3f

;const

int mod=

998244353

;const

double eps=

1e-20

;const

double pi=

acos(-

1);int s[n]

,ans[n]

,f[55][

5555];

pii g[n]

;signed

main()

sort

(g+1

,g+n+1)

;reverse

(g+1

,g+n+1)

;for

(int i=

1;i<=n;i++

) s[i]

=s[i-1]

+g[i]

.first;

memset

(f,0x3f

,sizeof f)

; f[0]

[0]=

0;for(

int i=

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

} cout<[m]

while

(i&&j)

else

i-=k;j-

=k;break;}

}}}for

(int i=

1;i<=n;i++

) cout<}

線性DP 餅乾

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

線性DP基礎 acwing 動態規劃

注意點 1 其實就是講所有走每一步的時候求大致值就好,然後這個值又會對下面進行影響,就像自己思考問題一樣 2 然後就是需要注意一下邊界問題,因為我們這邊求最大值,所以需要對邊界進行初始化 最長上公升子串行理解 1 有一說一,樣板題,很快就容易,就是當前這個值可以由前面 轉過來然後max最大長度就行,...

AcWing 274 移動服務 線性DP

乙個公司有三個移動服務員,最初分別在位置1,2,3處。如果某個位置 用乙個整數表示 有乙個請求,那麼公司必須指派某名員工趕到那個地方去。某一時刻只有乙個員工能移動,且不允許在同樣的位置出現兩個員工。從 p 到 q 移動乙個員工,需要花費 c p,q 這個函式不一定對稱,但保證 c p,p 0。給出n...