第一次做這種處理方法的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 時...