题目链接

https://vjudge.net/contest/397650#problem/A
https://nanti.jisuanke.com/t/48301

解题思路

简单dp+简单贪心,甚至不能算贪心。
S1:先用dp[i]存,在不算特殊区间的情况下,前i个位置染色的最大值;
S2:对pos的all赋值,pos[i].all表示区间左端点为i的特殊区间全涂为自己特定颜色的情况下,此区间为不加额外美感情况下,涂为纯色的美观度;
S3:比较每一段特殊区间涂为纯色的美观度和dp数组中此区间的美观度比较,若前者大,就把此区间换成纯色,反之不变。

AC代码

//题目:https://vjudge.net/contest/397650#problem/A
//题解: 
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=3e5+100;
struct P{
    int t;
    ll to,c,all;
}pos[N];
ll ans;
ll dp[N];
int n,m;
ll b[N],w[N];
void Input(){
    cin>>n>>m;
    memset(pos,0,sizeof pos);
    for(int i=1;i<=n;i++) cin>>b[i];
    for(int i=1;i<=n;i++) cin>>w[i];
    for(int i=1;i<=m;i++) {
        int t,l,r;
        ll c;
        cin>>t>>l>>r>>c;
        pos[l].t=t;
        pos[l].to=r;
        pos[l].c=c;
    }
} 
void BuildDP(){
    for(int i=1;i<=n;i++){
        dp[i]=dp[i-1]+max(b[i],w[i]);
    }
    ans=dp[n];
}
void BuildPos(){
    for(int i=1;i<=n;i++){
        int now=i;//勿忘! 
        if(pos[now].t==1) {
            for(;i<=pos[now].to;i++)
                pos[now].all+=b[i];
            i--;//勿忘! 
        }
        else if(pos[now].t==2){
            for(;i<=pos[now].to;i++)
                pos[now].all+=w[i];
            i--;//勿忘! 
        }    
    }
}
void solve(){
    for(int i=1;i<=n;i++){
        if(pos[i].t) ans+=max(0LL,pos[i].c+pos[i].all-(dp[pos[i].to]-dp[i-1]));    
    }
}
int main(){
    Input();
    BuildDP();
    BuildPos();
    solve();
    cout<<ans<<endl;
}

总结

这么简单一道题,wa了一次,debug了20min,发现是now没赋值,i忘记自减。WTCL!