codeforces 1133E K Balanced Teams
题目链接:http://codeforces.com/contest/1133/problem/E
题目大意:
在n个人中找到k个队伍。每个队伍必须满足最大值减最小值不超过5。求满足条件k个队伍人数的总和的最大值。
这个题写DP很多的人应该可以很快写出来吧,毕竟不是很难。
思路:
反正最多n^2种状态。用数组存就好了。
先排序。
对于每个点,dp[a][b]。表示a到n区间里分b个队伍的答案。
如果a是答案dp[a][b]所需要的,那么我们从a开始到a+i暴力一下(此时,x[a+i]-x[a]>5。x是排完序后的数组),dp[a][b]=dp[i][b-1]+i-a。(因为a已经组了队,所以b-1)
如果答案不需要a,dp[a][b]=dp[a+1][b]
真正的答案当然是两者的最大值。
所以dp[a][b]=max(dp[i][b-1]+i-a,dp[a+1][b])
找到状态转移就很容易写了。
#include <bits/stdc++.h> using namespace std; //#define int long long #define IOS ios::sync_with_stdio(false); #define endl "\n" #define MAX 5005 #define mod 1000000007 int x[MAX]; int n,m; int dp[MAX][MAX]; int DP(int a,int b){ if(b<=0||a>n){ return 0; } if(dp[a][b]){ return dp[a][b]; } int i=a; for(;i<=n;i++){ if(x[i]-x[a]>5){ break; } } dp[a][b]=max(DP(i,b-1)+i-a,DP(a+1,b)); return dp[a][b]; } signed main() { IOS; cin>>n>>m; for(int i=1;i<=n;i++){ cin>>x[i]; } sort(x+1,x+1+n); cout<<DP(1,m); return 0; }