SDF ABC162F 取数4
给定长度为 n的序列 A,请在这个序列中选择 n/2(向下取整)个数,并且这些数两两不相邻。请求出这些数的最大可能和。
#include<bitsstdc++.h>
#define N 1005
#define int long long
using namespace std;
int n, a[N], f[N][N];
signed main(){
cin>>n;
for(int i = 1; i <= n; i++) cin>>a[i];
memset(f, 0x80, sizeof f);
f[1][0] = 0, f[1][1] = a[1], f[0][0] = 0;
for(int i = 2; i <= n; i++){
for(int j = 1; j <= (i+1)/2; j++){
if(i >= 2) f[i][j] = f[i-2][j-1] + a[i];
f[i][j] = max(f[i][j], f[i-1][j]);
}
}
cout<<f[n][n/2]<<endl;
return 0;
}
/*
11
18 -28 18 28 -45 90 -45 23 -53 60 28
13
18 -28 18 28 -45 90 -45 23 -53 60 28 -74 -71
9
18 18 28 90 23 60 28 -74 -71
*/
/*
1.教学目标:可行性问题的处理
2.找规律或者推理出一些结论再考虑其他处理,比如dp
*/
#include<bitsstdc++.h>
#define N 200005
#define int long long
using namespace std;
int n, a[N];
signed main(){
cin>>n;
for(int i = 1; i <= n; i++) cin>>a[i];
// for(int i = 1; i <= n; i++){
// f[i] = f[i-2] + a[i];
// f[i] = g[i-3] + a[i];
// }
/*
//偶数
o o o o o o o o
1 o 1 o 1 o 1 o
o 1 o 1 o 1 o 1
1 o 1 o o 1 o 1 //空的两个只能放中间
//奇数
//g向上取整 //困难:选还是不选设不设状态, 奇偶放在一起转移么
*/
int g[N], f[N][3];
memset(g, 0x80, sizeof g); memset(f, 0x80, sizeof f);
f[3][1] = max(max(a[1],a[2]),a[3]), g[1] = a[1], f[1][1] = 0, f[0][0] = 0;
f[2][0] = max(a[1],a[2]);//缺
for(int i = 2; i <= n; i++){//f[][1]当前这个数是奇数/偶数
if(i%2 == 1 && i >= 2) g[i] = g[i-2] + a[i];
if(i%2 == 1 && i >= 4) f[i][1] = max(f[i][1], g[i-4] + max(a[i],max(a[i-2],a[i-1])));
if(i%2 == 1 && i >= 3) f[i][1] = max(f[i][1], f[i-3][0] + max(a[i],a[i-1]));
if(i%2 == 1 && i >= 2) f[i][1] = max(f[i][1], f[i-2][1] + a[i]);
if(i%2 == 0 && i >= 2) f[i][0] = max(f[i][0], f[i-2][0] + a[i]);
if(i%2 == 0 && i >= 3) f[i][0] = max(f[i][0], g[i-3] + max(a[i],a[i-1]));
}
// cout<<"f[2] "<<f[2][0]<<" "<<f[3][1]<<endl;
if(n % 2 == 1)
cout<<f[n][1]<<endl;
else
cout<<f[n][0]<<endl;
return 0;
}
/*
13
18 -28 18 28 -45 90 -45 23 -53 60 28 -74 -71
5
28 90 60 -74 -71
5
6 9 2 -4 -3
2
10 -10
*/
浙公网安备 33010602011771号