Codeforces Round #260 (Div. 1) A - Boredom DP

点击打开链接

题意:

给你n个数,你每次可以选择删除去一个数x,但是等于x+1和等于x-1的数都得删去

你每一次操作可以得x分


思路一:

dp[i]表示到i后能够得到的最大分数

dp[i]=max(dp[i-1],dp[i-2]+a[i]*i;

代码:

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e5+10;
 5 inline ll read(){
 6     ll x=0,f=1;char ch=getchar();
 7     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 8     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 9     return x*f;
10 }
11 
12 ll a[maxn],dp[maxn];
13 
14 int main(){
15     int n;
16     cin >> n;
17     for(int i=1; i<=n; i++){
18         ll x; cin >> x;
19         a[x]++;
20     }
21 
22     memset(dp,0,sizeof(dp));
23 
24     for(int i=1; i<maxn; i++){
25         dp[i] = max(dp[i-1],dp[i-2]+a[i]*i);
26     }
27 
28     cout << dp[maxn-1] << endl;
29  
30     return 0;
31 }

 

思路二:

 

用计数排序统计数字的个数

dp[ i ][ 0 ]表示不删除 i ,dp[ i ][ 1 ]表示删除 i 

dp[ i ][ 0 ] = max( dp[ i-1 ][ 1 ] , dp[ i-1 ][ 0 ] );
dp[ i ][ 1 ] = dp[ i-1 ][ 0 ] + i * a[ i ];

代码:

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e5+10;
 5 const int INF = 0x3f3f3f3f;
 6 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
 7 inline ll read(){
 8     ll x=0,f=1;char ch=getchar();
 9     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
10     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
11     return x*f;
12 }
13 //////////////////////////////////////////////////////////////////////////
14 
15 ll a[maxn],dp[maxn][2];
16 int mx=-1;
17 
18 int main(){
19     int n; n = read();
20     for(int i=1; i<=n; i++){
21         int x; x = read();
22         a[x]++;
23         mx = max(x,mx);
24     }
25 
26     for(int i=1; i<=mx; i++){
27         dp[i][1] = dp[i-1][0]+a[i]*i;    // dp[i][1] 表示这个数删
28         dp[i][0] = max(dp[i-1][1],dp[i-1][0]); // dp[i][0] 表示这个数不删
29     }
30 
31     cout << max(dp[mx][0],dp[mx][1]) << endl;
32     return 0;
33 }

 

滚动优化:

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e5+10;
 5 const int INF = 0x3f3f3f3f;
 6 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
 7 inline ll read(){
 8     ll x=0,f=1;char ch=getchar();
 9     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
10     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
11     return x*f;
12 }
13 //////////////////////////////////////////////////////////////////////////
14 
15 ll a[maxn],dp[2][2];
16 int mx=-1;
17 
18 int main(){
19     int n; n = read();
20     for(int i=1; i<=n; i++){
21         int x; x = read();
22         a[x]++;
23         mx = max(x,mx);
24     }
25 
26     int now = 0, pre = 1;;
27     for(int i=1; i<=mx; i++){
28         
29         dp[now][1] = dp[pre][0]+a[i]*i;    // dp[now][1] 表示这个数删
30         dp[now][0] = max(dp[pre][1],dp[pre][0]); // dp[now][0] 表示这个数不删
31         swap(now, pre);
32     }
33 
34     dp[now][0] = max(dp[now][0],dp[pre][0]);
35     dp[now][1] = max(dp[now][1],dp[pre][1]);
36 
37     ll ans = max(dp[now][0],dp[now][1]);
38     cout << ans << endl;
39 
40     return 0;
41 }

 

posted @ 2017-02-21 17:11  _yxg123  阅读(117)  评论(0编辑  收藏  举报