蓝桥杯_历届试题 对局匹配

匿名 (未验证) 提交于 2019-12-03 00:18:01

题目中只有积分差为k的才不能同时选,那么也就是和当前状态下只有差为k的才能产生相互影响,别的就没有一点影响了,那么我们把能够相互影响的找出来,在每一组相互影响的里面找到最大值,在将每组的最大值加起来,就是最终的结果

在一组相互影响的里面,当前状态j只有两种,一种是选这个,另一种是不选这个,如果选的话dp[j] = dp[j-2] + cnt[j] (cnt表示j状态的数量),不选择的话:dp[j] = dp[j-1],那么最终的状态转移方程为dp[j] = max(dp[j-1],dp[j-2] + cnt[j])

#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <cmath> #include <algorithm> #define INF 0x3f3f3f3f #define ll long long using namespace std; const int MAXN = 101000; int a[MAXN],num[MAXN],n,k; int cnt[MAXN]; int dp[MAXN];  //dp[i][0]:表示不选当前分数的情况  dp[i][1]:选择当前分数的情况 bool vis[MAXN]; int main() {     int max_num = 0;     memset(cnt,0,sizeof(cnt));     memset(dp,0,sizeof(dp));     memset(vis,false,sizeof(vis));     scanf("%d%d",&n,&k);     for(int i =1 ;i <= n;i ++)     {         scanf("%d",&a[i]);         cnt[a[i]] ++;         max_num = a[i] > max_num?a[i]:max_num;     }     if(k == 0)     {         int ans = 0;         for(int i = 0;i <= max_num;i ++)             if(cnt[i])                 ans ++;         printf("%d\n",ans);     }     else     {         int ans = 0;         sort(a+1,a+1+n);         int index = 0;         num[index++] = a[1]; //得到不重复的输入序列,0~index    他们分别对应的个数为cnt[num[i]]         for(int i = 2;i <= n;i ++)         {             if(num[index-1] != a[i])                 num[index++] = a[i];         }         int pos,temp[MAXN];         for(int i = 0;i < index;i ++)         {             pos = 0;             if(vis[num[i]] == false)             {                 int p = num[i];                 while(1)   //从这个元素向后寻找相差大小等于k的一系列数组                 {                     temp[pos++] = p;   vis[p] = true;                     if(cnt[p + k] == 0) break;   //不存在这个数了                     p = p + k;    //temp里面存储的是当前对应位置上的数字                 }             }             if(pos == 1)                 ans += cnt[temp[0]];             else if(pos >= 2)             {                 dp[0] = cnt[temp[0]],dp[1] = max(dp[0],cnt[temp[1]]);                 for(int j = 2;j < pos;j ++)                     dp[j] = max(dp[j-1],dp[j-2] + cnt[temp[j]]);                 ans += dp[pos-1];             }         }         printf("%d\n",ans);      } } 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!