cf 455A Boredom (dp)

455A

普及组dp题居然不会了,要尽快回到状态才行。

题意就是给定一个序列,然后玩家每次选择一个数并得该数值的分,并且选了\(a_i\)以后,值为\(a_{i}-1\)\(a_{i}+1\)都不能选了。要求最大化得分。

这样的dp,和值域有关。考虑将值域作为状态。

\(dp(i,1)\)\([1,i]\)的数被处理,并且\(a_i\)被选的最大得分。

\(dp(i,0)\)\([1,i]\)的数被处理,并且\(a_i\)没被选的最大得分。

转移:

\(dp(i,1)=dp(i-1,0)+a_i\)

\(dp(i,0)=max(dp(i-1,1),dp(i-1,0))\)

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

template<typename T> inline T readin(T &rt) {
  char c; T tmp=0,x=1; c=getchar();
  while(c>'9' || c<'0') {if(c=='-') x=-1; c=getchar();}
  while(c>='0' && c<='9') {tmp=tmp*10+c-'0'; c=getchar();}
  return rt=tmp*x;
}

const int maxN=100000+10;
int n,a[maxN],hav[maxN];
ll dp[maxN][2];

int main() {
  readin(n);
  int maxAi=0;
  for(int i=1;i<=n;i++) readin(a[i]),hav[a[i]]++,maxAi=max(maxAi,a[i]);
  ll ans=0;
  for(int i=1;i<=maxAi;i++) {
    dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
    dp[i][1]=dp[i-1][0]+1ll*hav[i]*i;
    ans=max(ans,dp[i][0]); ans=max(ans,dp[i][1]);
  }
  printf("%lld\n",ans);
  return 0;
}

猜你喜欢

转载自www.cnblogs.com/darkroome/p/9218763.html