AtCoder Beginner Contest 162 比赛人数10673 快,比赛开始后5分钟看到所有题
AtCoder Beginner Contest 162 F Select Half 动归dp
总目录详见https://blog.csdn.net/mrcrack/article/details/104454762
在线测评地址https://atcoder.jp/contests/abc162/tasks/abc162_f
思路摘自https://www.cnblogs.com/Kanoon/p/12688882.html
手工算法如下
带选数组位置 1 2 3 4 5 6 7
需要选数的数量 0 1 1 2 2 3 3
dp[0]=0,dp[1]=0
dp[2]若选了a[2],值为dp[0]+a[2]; 若不选a[2],值为sum[1]=a[1].
dp[3]若选了a[3],值为dp[1]+a[3]; 若不选a[3],值为dp[2].
dp[4]若选了a[4],值为dp[2]+a[4]; 若不选a[4],值为sum[3]=a[1]+a[3].
dp[5]若选了a[5],值为dp[3]+a[5]; 若不选a[5],值为dp[4].
dp[6]若选了a[6],值为dp[4]+a[6]; 若不选a[6],值为sum[5]=a[1]+a[3]+a[5].
dp[7]若选了a[7],值为dp[5]+a[7]; 若不选a[7],值为dp[6].
AC代码如下
#include <cstdio>
#include <algorithm>
#define maxn 200010
#define LL long long
using namespace std;
int a[maxn];
LL dp[maxn],sum[maxn];
int main(){
int n,i;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
for(i=1;i<=n;i++)
if(i%2)sum[i]=sum[i-1]+a[i];//奇数项之和
else sum[i]=sum[i-1];
for(i=2;i<=n;i++)
if(i&1)dp[i]=max(dp[i-2]+a[i],dp[i-1]);//i是奇数,i/2==(i-1)/2
else dp[i]=max(dp[i-2]+a[i],sum[i-1]);//i是偶数
printf("%lld\n",dp[n]);
return 0;
}
编后感,动归略微有了感觉,好现象。