首页 > 其他 > 详细

CF 445A 简单DP

时间:2015-08-11 07:16:09      阅读:264      评论:0      收藏:0      [点我收藏+]

今天早上找一道题的bug,还是找不出来,下午刷了几道水题,晚上准备回家的事,

然后本来想打CF的,一看,数学场,不打了。

 

这道题的题意:

给出一个序列,每次你可以从这个序列里面选择一个数ak,删除,然后你的得分+ak,

代价是序列里面值为ak+1,ak-1的元素都删除

 

问:你能得到的最大得分是多少

 

思路:

你若删除了一个值为a的数,你的得分就是a*序列里面a的个数

因为a+1和a-1都被删除了,则其余的a不会被a+1,a-1这种情况删除了,你一定可以得到所有a的分数

所以这道题就是:在序列里面选择一些数值,你的得分+数值*该值出现的个数,并且,

数值+1和数值-1的数你就不能选了。

 

num[i]表示值i出现的次数。

_max表示出现的最大的值

dp[i][0]:表示从值1选择到i,如果不选择值i,可以得到的最大分数

dp[i][1]:表示从值1选择到值i,如果选择了值i,可以得到的最大分数。

 

 

注意:

1.这道题最后的结果要long long

2.小心中间过程溢出,我就是这个贡献了2个wa

3.CF的long long 要用cout输出

 

技术分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 
 5 using namespace std;
 6 #define LL long long
 7 const int maxn=1e5+10;
 8 
 9 inline LL max(LL x,LL y)
10 {
11     return x>y?x:y;
12 }
13 
14 int a[maxn];
15 LL dp[maxn][2];
16 
17 int main()
18 {
19     int n;
20     scanf("%d",&n);
21     int _max=-1;
22     memset(a,0,sizeof a);
23     for(int i=1;i<=n;i++)
24     {
25         int u;
26         scanf("%d",&u);
27         a[u]++;
28         if(u>_max)
29             _max=u;
30     }
31 
32     memset(dp,0,sizeof dp);
33     for(int i=1;i<=_max;i++)
34     {
35         dp[i][1]=dp[i-1][0]+(LL)a[i]*i;
36         dp[i][0]=max(dp[i-1][1],dp[i-1][0]);
37     }
38 
39     cout<<max(dp[_max][1],dp[_max][0])<<endl;
40 
41     return 0;
42 }
View Code

 

CF 445A 简单DP

原文:http://www.cnblogs.com/-maybe/p/4719861.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!