Codeforces Round #708 (Div. 2) D. Genius 动态规划

  • 原题链接
    在这里插入图片描述

  • 测试样例

    input
    5
    4
    1 2 3 4
    5 10 15 20
    4
    1 2 1 2
    5 10 15 20
    4
    2 2 4 1
    2 8 19 1
    2
    1 1
    6 9
    1
    1
    666
    output
    35
    30
    42
    0
    0

  • Note

    In the first test case optimal sequence of solving problems is as follows:
    1→2, after that total score is 5 and IQ=2
    2→3, after that total score is 10 and IQ=4
    3→1, after that total score is 20 and IQ=6
    1→4, after that total score is 35 and IQ=14
    In the second test case optimal sequence of solving problems is as follows:
    1→2, after that total score is 5 and IQ=2
    2→3, after that total score is 10 and IQ=4
    3→4, after that total score is 15 and IQ=8
    4→1, after that total score is 35 and IQ=14
    In the third test case optimal sequence of solving problems is as follows:
    1→3, after that total score is 17 and IQ=6
    3→4, after that total score is 35 and IQ=8
    4→2, after that total score is 42 and IQ=12

  • 解题思路
    这道题我们不必纠结于 I Q IQ IQ,因为我们如果是做了先做第 i i i道题后做第 j j j道题或者相反,这样我们的 I Q IQ IQ= ∣ 2 i − 2 j ∣ |2^i-2^j| 2i2j,那么我们就保证这处于 i i i j j j之间的题不能做,只有这样才符合条件。所以我们可以枚举 i i i j j j,同时我们用 d p i dp_i dpi来表示以问题 i i i作为终止点的最大分数,那么在 i i i j j j之中,我们有两种选择,一种是先 i i i j j j,一种是先 j j j i i i,这种它们的得分是一样的,但是状态转移却不一样。 知道了这个,那么我们就可以进行动态规划设计了,初始的 d p dp dp值都为 0 0 0,我们先枚举一个题序号 j j j,在从小于序号 j j j的题中依次挑选进行状态转移即可。最后得到的 d p dp dp数组,我们需要找到这个最大值,这个即是答案。

  • 代码

/**
* @filename:D.cbp
* @Author : pursuit
* @Blog:unique_pursuit
* @email: 2825841950@qq.com
* @Date : 2021-03-18-11.04.27
*/
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn=1e5+5;
const int mod=1e9+7;

int t,n;
void solve(){
    vector<ll> s(n),tag(n),dp(n,0);//dp[i]表示以问题i结尾的最大分数。
    for(int i=0;i<n;i++){
        cin>>tag[i];
    }
    for(int i=0;i<n;i++){
        cin>>s[i];
    }
    for(int j=1;j<n;j++){
        //这里我们枚举状态点。我们从低到高枚举状态点这样保证了我们的IQ是永远满足条件的。
        for(int i=j-1;i>=0;i--){
            if(tag[i]==tag[j]){
                //标记相同,不能解决问题。
                continue;
            }
            ll dpi=dp[i],dpj=dp[j],p=abs(s[i]-s[j]);
            dp[i]=max(dp[i],dpj+p);//这个表示我们解决完j后去解决i
            dp[j]=max(dp[j],dpi+p);
        }
    }
    ll maxx=0;
    for(auto x:dp){
        maxx=max(maxx,x);
    }
    cout<<maxx<<endl;
}
int main(){
    while(cin>>t){
        while(t--){
            cin>>n;
            solve();
        }
    }
    return 0;
}

posted @   unique_pursuit  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示