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

  • 原题链接
    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| ∣2i−2j∣,那么我们就保证这处于 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;
}

上一篇:Genius's Gambit


下一篇:SWUST OJ 1027.舞伴问题