题目链接
题意:
给定长度为n的序列,选择任意数a[k]删除并获得a[k]的价值,同时等于a[k]-1 a[k]+1的数也将全部被删除,求获取价值的最大值
输入:
长度n
n个数
输出:
价值最大值
样例:
题目分析:
首先先贪心选取发现无法保证最优解,当前数的选取取决于前一个数的状态,且每一步的选取的价值等于当前数*次数
建立dp[N][2]数组,表示x选或不选的最大价值,dp[i][0]表示不选,dp[i][1]表示选
状态转移 :
dp[i][1]=dp[i-1][0]+i*cnt[i]; //当前数选
dp[i][0]=max(dp[i-1][0],dp[i-1][1]); //当前数不选
代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define pf push_front
#define all(x) (x).begin(),(x).end()
#define fast ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
typedef long long ll;
typedef set<int>::iterator SIT;
int dx[]={0,-1,0,1},dy[]={-1,0,1,0};
const int N=1e5+10,INF=0x3f3f3f3f;
int n;
ll dp[N][3],cnt[N];
int main()
{
fast;
int maxn=-1;
cin>>n;
for(int i=1;i<=n;i++){
int x;
cin>>x;
cnt[x]++;
maxn=max(maxn,x);
}
for(int i=1;i<=maxn;i++){
dp[i][1]=dp[i-1][0]+i*cnt[i]; //当前数选
dp[i][0]=max(dp[i-1][0],dp[i-1][1]); //当前数不选
}
cout<<max(dp[maxn][0],dp[maxn][1])<<endl;
return 0;
}