一篇好文章:https://blog.csdn.net/flyawayl/article/details/79068946
下面是自己寫的代碼:
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
#define max_score 100005
#define max 100005
int cnt[max_score], val[max], dp[max];
int maxfun(int a, int b) {
if (a > b)return a;
else return b;
}
int main() {
int N, K,i,temp,ans=0,j;
memset(cnt, 0, sizeof(cnt));
scanf("%d %d", &N, &K);
//下面事統計每個分數有多少人
for (i = 0; i < N; i++) {
scanf("%d", &temp);
cnt[temp]++;
}
//如果K=0,那麼有多少不重複的分數就是最多有多少人
if (K== 0) {
for (i = 0; i <= max_score; i++) {
if (cnt[i]) ans++;
}
}
else {
for (i = 0; i < K; i++) {
int m = 0;//下面的for循環才實現了真正意義上的分組,每一組從i開始,每次遞增k;val記錄了每一個數對應的人數。每開始新的組,下標都要清0
for (j = i; j <= max_score; j = j + K) {
val[m++] = cnt[j];
}
dp[0] = val[0];//下面的for循環纔是真正的動態規劃
for (j = 1; j < m; j++) {
if (j == 1) {
dp[1] = maxfun(dp[0], val[1]);
}
else {
dp[j] = maxfun(dp[j - 2] + val[j], dp[j - 1]);
}
}
ans = ans + dp[m - 1];//每次對一個小組進行動態規劃後都進行累加
}
}
cout << ans;
}