zoukankan      html  css  js  c++  java
  • CF264C Choosing Balls

    Solution

    首先明确的是对每一次询问分开处理。

    然后因为要求最大价值,可以想到用DP去做。设 (d_{i,j}) 表示前 (i) 个元素,以 (j) 颜色为结尾的最大价值。可以发现,每一个 (i) 最多只会更新一个 (dp) ,所以可以将第一维省略掉。

    接下来我们思考第 (i) 个球会从哪些情况继承也就是状态转移:

    1.这是子序列第 (1) 个球: (b imes v_i)

    2.从上一个和它颜色相同的球的结尾的子序列转移: (dp_{c_i}+a imes v_i)

    3.从和它颜色不一样的球的结尾的最大价值子序列转移: (maxlimits_{c_i ot=c_j}{dp_j}+b imes v_i)

    但是因为3转移单次复杂度为 (O(n)) ,所以我们需要 (O(1)) 找到最优的那个 (j)

    因为 (dp) 数组在转移后是单调不减的,所以可以保留最大值的颜色。

    但是如果只保留转移前最大值的颜色,那么可能最大值的颜色和 (i) 一样,所以还要保留次大值的颜色,这样就能保证两个中起码有一个是3转移需要的。

    然后更新最大值,次大值颜色, (dp_{c_i}) 的值和 (ans) 即可。

    代码

    #include<bits/stdc++.h>
    #define int long long
    
    using namespace std;
    const int N=1e5+5,INF=1e18;
    int n,m,a,b,ans;
    int v[N],c[N],dp[N];
    
    signed main(){
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=n;i++) scanf("%lld",&v[i]);
        for(int i=1;i<=n;i++) scanf("%lld",&c[i]);
        while(m--){
            ans=0;
            scanf("%lld%lld",&a,&b);
            for(int i=1;i<=n;i++) dp[i]=-INF;
            int t1=0,t2=0,tmp=0;
            for(int i=1;i<=n;i++){
                tmp=max(b*v[i],dp[c[i]]+a*v[i]);
                if(c[i]!=t1) tmp=max(tmp,dp[t1]+b*v[i]);
                else tmp=max(tmp,dp[t2]+b*v[i]);
                if(tmp>dp[t1]){
                    if(t1!=c[i]){
                        t2=t1;
                        t1=c[i];
                    }
                    else t1=c[i];
                }
                else if(tmp>dp[t2]&&c[i]!=t1) t2=c[i];
                dp[c[i]]=max(dp[c[i]],tmp);
                ans=max(ans,tmp);
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    模块二:操作系统windows 7 的使用
    茶卡盐湖
    css元素居中指南
    新的CMS套站
    写响应式页面
    积累
    jquery方法整理
    积累 做网站添加的 所有动态效果
    产品中心有二级三级栏目。
    aspcms
  • 原文地址:https://www.cnblogs.com/jasony/p/13817527.html
Copyright © 2011-2022 走看看