DP的序--Codeforces626F. Group Projects
Posted Blue233333
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DP的序--Codeforces626F. Group Projects相关的知识,希望对你有一定的参考价值。
$n \leq 200$个数,$ \leq 500$,$K \leq 1000$代价内的数字分组有多少?一个分组的代价是分成的每个小组的总代价;一个小组的代价是极差。
问的极差那就从极入手嘛。一个小组只有最大和最小值是有用滴!那就来分这些最大最小值。
由于考虑大小,不如先把数列排个序。这样的话,可以表示出那种“有几个小组分不满”的形似插头DP的状态,在移动到下一个数时代价加上当前数和下一个数的差乘上还没分配满的小组数即可。具体,$f(i,j,k)$表示前$i$个数$j$个小组还没满,当前代价$k$的方案,如此不需要知道最小值们是谁,只需在$i$移动到$i+1$时,每个没配满的小组加上$a_{i+1}-a_i$的代价即可,因此没配满小组数$j$就可以计算代价。转移的话,分$i$单独一组、新开一个未满组、加入之前一个未满组、充当之前一个未满组的最大值,来转移。
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 //#include<math.h> 5 //#include<queue> 6 //#include<vector> 7 #include<algorithm> 8 //#include<iostream> 9 //#include<assert.h> 10 using namespace std; 11 12 int n,K; 13 const int mod=1e9+7; 14 int a[222],f[2][222][1111],cur; 15 16 int main() 17 { 18 scanf("%d%d",&n,&K); 19 for (int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+1+n); 20 cur=0; f[0][0][0]=1; 21 for (int i=1;i<=n;i++) 22 { 23 for (int j=0;j<=n;j++) 24 for (int k=0,tmp=j*(a[i]-a[i-1]),to=K-tmp;k<=to;k++,tmp++) if (f[cur][j][k]) 25 { 26 f[cur^1][j+1][tmp]+=f[cur][j][k]; f[cur^1][j+1][tmp]-=f[cur^1][j+1][tmp]>=mod?mod:0; 27 f[cur^1][j][tmp]+=(j+1)*1ll*f[cur][j][k]%mod; f[cur^1][j][tmp]-=f[cur^1][j][tmp]>=mod?mod:0; 28 if (j>0) 29 {f[cur^1][j-1][tmp]+=j*1ll*f[cur][j][k]%mod; f[cur^1][j-1][tmp]-=f[cur^1][j-1][tmp]>=mod?mod:0;} 30 } 31 memset(f[cur],0,sizeof(f[cur])); 32 cur^=1; 33 } 34 35 int ans=0; for (int i=0;i<=K;i++) ans+=f[cur][0][i],ans-=ans>=mod?mod:0; 36 printf("%d\n",ans); 37 return 0; 38 }
以上是关于DP的序--Codeforces626F. Group Projects的主要内容,如果未能解决你的问题,请参考以下文章
[Codeforces 626F]Group Projects
Codeforces626 F. Group Projects(dp,状态优化)
Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics)