最大和

70 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第7 天,点击查看活动详情

小蓝在玩一个寻宝游戏, 游戏在一条笔直的道路上进行, 道路被分成了 �n 个方格, 依次编号 1 至 �n, 每个方格上都有一个宝物, 宝物的分值是一个整数 (包括正数、负数和零), 当进入一个方格时即获得方格中宝物的分值。小蓝可 以获得的总分值是他从方格中获得的分值之和。

小蓝开始时站在方格 1 上并获得了方格 1 上宝物的分值, 他要经过若干步 到达方格 �n。

当小蓝站在方格 �p 上时, 他可以选择跳到 �+1p+1 到 �+�(�−�)p+D(n−p) 这些方格 中的一个, 其中 �(1)=1,�(�)(�>1)D(1)=1,D(x)(x>1) 定义为 �x 的最小质因数。

给定每个方格中宝物的分值, 请问小蓝能获得的最大总分值是多少。

输入格式

输入的第一行包含一个正整数 �n 。

第二行包含 �n 个整数, 依次表示每个方格中宝物的分值。

输出格式

输出一行包含一个整数, 表示答案。

样例输入


5

1 -2 -1 3 5

样例输出


8

样例输出

最优的跳跃方案为: 1→3→4→51→3→4→5 。

评测用例规模与约定

对于 4040 的评测用例, 1≤�≤1001≤n≤100 。

对于 8080 的评测用例, 1≤�≤10001≤n≤1000 。

对于所有评测用例, 1≤�≤100001≤n≤10000, 每个宝物的分值为绝对值不超过 105105 的整数。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

分析

dp即可,我开始看成了贪心,走向了不归路,然后寄了,记住要先判断质因数。

代码

#include <iostream>
#include <map>
#include <cstring>
#define ll long long
using namespace std;
const int N=10010;
int d[N],n,w[N],dp[N];
bool check(int x){
    for(int i=2;i<=x/i;i++){
        if(x%i==0) return false;
    }
    return true;
}
int main(){
    cin>>n;
//    for(int i=2;i<=100;i++){
//        if(check(i)) cout<<i<<endl;
//    }
    d[1]=1;
    for(int i=1;i<=n;i++) cin>>w[i];
    for(int i=2;i<=n;i++){
        if(check(i)){
            d[i]=i;
            continue;
        }
        for(int j=2;j<=i;j++){
            if(i%j==0){
                d[i]=j;
                break;
            }
        }
    }
    memset(dp,0xcf,sizeof dp);
    dp[1]=w[1];
    for(int i=1;i<=n;i++){
        int j=d[n-i];
        for(int k=i+1;k<=min(i+j,n);k++){
            dp[k]=max(dp[k],dp[i]+w[k]);
        }
    }
    cout<<dp[n]<<endl;
    return 0;
}

QAQ