CodeForces

来源:互联网 发布:mac os x 10.7镜像下载 编辑:程序博客网 时间:2024/06/16 11:18


传送门



题目大意:输入一个序列的整数,进行删除操作,   如果删除 x  那么队列中所有的 x+1  和  x-1 (注意时值,不是下标,一开始理解错题意了,坑死....) 就要删除.

      同时获得 x的个数乘以x的分数,  求出最高得分。   简单的01背包问题,  就是删除还是不删除当前数字,比较往前数两个加上但前的值  与前一个进行比较就好。


一开始的AC 代码:

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cstring>using namespace std;long long cnt[100050];long long dp[100050];int main(){int n;int maxa;memset(dp, 0, sizeof(dp));scanf("%d", &n);int a;for(int i=0; i<n; i++){scanf("%d", &a);if(a > maxa) maxa = a;cnt[a] ++;}long long ans = 0;dp[1] = cnt[1];for(int i=1; i<= maxa; i++){if(i-2 >= 0) dp[i] = max(dp[i-1], dp[i-2]+ i*cnt[i]);if(dp[i] > ans) ans = dp[i];}cout << ans << endl;return 0;}



后来改良版,优化了空间(减少了一个数组):

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cstring>using namespace std;long long cnt[100050];int main(){int n;int maxa = 0;scanf("%d", &n);int a;for(int i=0; i<n; i++){scanf("%d", &a);if(a > maxa) maxa = a;cnt[a]++;}long long ans = cnt[1];long long x1 = 0;long long x2 = 0;long long t;for(int i=1; i<= maxa; i++){t = x2;x2 = max(x2, x1 + i*cnt[i]);if(x2 > ans) ans = x2;x1 = t;}cout << ans << endl;return 0;}