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;
}


 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号