Live2d Test Env

hiho1601最大分数 DP

                                          #1601 : 最大得分

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

小Hi和小Ho在玩一个游戏。给定一个数组A=[A1, A2, ... AN],小Hi可以指定M个不同的值S1,S2, S3 ... SM,这样他的总得分是 ΣSi × count(Si)。(count(Si)是数组中与Si相等的元素的个数)。

为了增加难度,小Ho要求小Hi选择的S1..SM其中任意两个Si和Sj都满足|Si-Sj| > 1。

你能帮助小Hi算出他最大得分是多少吗?

输入

第一行包含两个整数N和M。  

第二行包含N个整数A1, A2, ... AN。  

对于30%的数据,1 ≤ M ≤ N ≤ 10  

对于100%的数据,1 ≤ M ≤ N ≤ 1000 1 ≤ Ai ≤ 100000

输出

最大得分

样例输入
5 2  
1 2 1 2 3
样例输出
        5
 
dp[i][j]表示前i个用了j个的最大值
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<memory>
#include<cstring>
using namespace std;
const int maxn=1010;
long long  a[maxn],b[maxn],c[maxn];
long long  dp[maxn][maxn],Max;
int main()
{
    long long  n,i,j,k,m,cnt=0;
    scanf("%lld%lld",&n,&m);
    for(i=1;i<=n;i++) scanf("%lld",&a[i]);
    sort(a+1,a+n+1);
    for(i=1;i<=n;i++){
       if(a[i]!=a[i-1]) {
           b[++cnt]=a[i]; 
           c[cnt]=1;    
       }
       else  c[cnt]++;
    }
    memset(dp,-1,sizeof(dp));
    for(i=0;i<=cnt;i++) dp[i][0]=0;
    dp[1][1]=b[1]*c[1];
    Max=dp[1][1];
    for(i=2;i<=cnt;i++)
      for(j=1;j<=m;j++){
            dp[i][j]=dp[i-1][j];//不用第i个
            if(b[i]-b[i-1]>1) dp[i][j]=max(dp[i][j],dp[i-1][j-1]+b[i]*c[i]);//要第i个,前一个也要
            else dp[i][j]=max(dp[i][j],dp[i-2][j-1]+b[i]*c[i]);//要第i个,而前一个不要
            Max=max(Max,dp[i][j]);
      } 
    printf("%lld\n",Max);
    return 0;
}

 




posted @ 2017-10-22 10:30  nimphy  阅读(223)  评论(0编辑  收藏  举报