标签:i++ 玩家 IV div turn 转移 namespace 状态 tchar
普及组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;
}
标签:i++ 玩家 IV div turn 转移 namespace 状态 tchar
原文地址:https://www.cnblogs.com/darkroome/p/9218763.html