1. 程式人生 > >Codeforces 999F Cards and Joy(二維DP)

Codeforces 999F Cards and Joy(二維DP)

++i 代碼 鏈接 als 個人 href rds a+b min

題目鏈接:http://codeforces.com/problemset/problem/999/F

題目大意:
有n個人,n*k張卡牌,每個人會發到k張卡牌,每個人都有一種喜歡的卡牌f[i],當一個人擁有x張喜歡的卡牌時會增加
h[x]點愉悅值,求合理的發牌方式使得所有人的愉悅值之和最大,輸出最大愉悅值。
解題思路:
設dp[x][y]表示當x個人擁有同一種喜歡的卡牌且該卡牌有y張時的最大愉悅值。
則狀態轉移的根本取決於第x個人擁有幾張喜歡的卡牌,所以得到狀態轉移方程:
for (int i = 0; i <= min(k,y); ++i) dp[x][y] = max(dp[x - 1][y], dp[x-1][y-i] + h[i])

代碼

 1 #include<bits/stdc++.h>
 2 #define lc(a) (a<<1)
 3 #define rc(a) (a<<1|1)
 4 #define MID(a,b) ((a+b)>>1)
 5 #define fin(name)  freopen(name,"r",stdin)
 6 #define fout(name) freopen(name,"w",stdout)
 7 #define clr(arr,val) memset(arr,val,sizeof(arr))
 8 #define
_for(i,start,end) for(int i=start;i<=end;i++) 9 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0); 10 using namespace std; 11 typedef long long LL; 12 const int N=1e5+5; 13 const int INF=0x3f3f3f3f; 14 const double eps=1e-10; 15 16 int dp[505][5005],f[N],c[N],h[11]; 17 18 int main(){
19 FAST_IO; 20 int n,k; 21 cin>>n>>k; 22 int x; 23 for(int i=1;i<=n*k;i++){ 24 cin>>x; 25 c[x]++; 26 } 27 for(int i=1;i<=n;i++){ 28 cin>>x; 29 f[x]++; 30 } 31 for(int i=1;i<=k;i++){ 32 cin>>h[i]; 33 } 34 for(int i=1;i<=n;i++){ 35 for(int j=1;j<=n*k;j++){ 36 for(int t=1;t<=min(j,k);t++){ 37 dp[i][j]=max(dp[i][j],dp[i-1][j-t]+h[t]); 38 } 39 } 40 } 41 int ans=0; 42 for(int i=1;i<N;i++){ 43 ans+=dp[f[i]][c[i]]; 44 } 45 cout<<ans<<endl; 46 return 0; 47 }

Codeforces 999F Cards and Joy(二維DP)