2024牛客暑期多校训练营2

H.Instructions Substring
题目大意:给出一段长为 n 的字符串,其中WASD分别代表向上下左右走,给出目的地 (x,y) ,选择一段连续子序列使得从 (0,0) 出发可以经过目的地,求这样的子序列的总数。
思路:用前缀和记录到 i 为止到达的位置,从前往后遍历右端点 r ,找到恰好到达目的地的 l 的数量,即 prex[i]x,prey[i]y 的数量,这些数量可以使 rn 的所有右端点成立(经过目的地)。做完后将这些已经用过的前端点归0,防止后面的后端点再次使用而重复。
注意:由于一开始就在(0,0),若目的地为(0,0)则需特判;

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
const int N = 9e6 + 10;
using namespace std;
const int mod = 998244353;

int prex[200005],prey[200005];

map<pair<int,int> ,int>mp;
void solve(){
    int n,x,y;cin>>n>>x>>y;
    for(int i=1;i<=n;i++){
        char c;cin>>c;
        if(c=='D'){
            prex[i]=prex[i-1]+1;
            prey[i]=prey[i-1];
        }
        else if(c=='A'){
            prex[i]=prex[i-1]-1;
            prey[i]=prey[i-1];
        }
        else if(c=='S'){
            prex[i]=prex[i-1];
            prey[i]=prey[i-1]-1;
        }else {
            prex[i]=prex[i-1];
            prey[i]=prey[i-1]+1;
        }
    }
    if(x!=0||y!=0) mp[{0,0}]++;
    int ans=0;
    for(int i=1;i<=n;i++){
        mp[{prex[i], prey[i]}]++;
        ans+=mp[{prex[i]-x,prey[i]-y}]*(n-i+1);
        mp[{prex[i]-x,prey[i]-y}]=0;
    }
    cout<<ans<<'\n';
}
signed main(){
    ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    int _=1;
//    cin>>_;
    while(_--)solve();
}

I:Red Playing Cards
题目大意:有 2n 张牌,牌上数字为 1n 的牌每种两张,你可以选择数字相同的两张牌将他们以及他们中间的牌删去,并获得选择的数字乘删去牌的数量的贡献,求删到不可删为止的最大贡献。
思路:用 mx[num] 表示 num.lnum.r 可实现的最大贡献,用 dp[i] 表示 inum.l 的最大贡献。从大到小更新 mx[num] 的值, date[i] 存储 i 位置上的数。
1.如果两 num 之间的牌的值都比 num 小,那么一定删去这两个相同数字,并得到 dp[num.r] 的贡献。E:5123412345,一定删去5,得到50的贡献。
2.如果两 num 之间 i 位置上出现一张牌的值为 k ,且 k>num 那么就判断是删去这个大数的最大贡献大还是不删更大。dp[i]=max(dp[i],dp[date[i].l]+dp[k])
3.由于数字0的贡献与长度无关,在原数列两头加上0,就可以得到 12n 的最大贡献 mx[0]

点击查看代码
#include<bits/stdc++.h>

#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
const int N = 9e6 + 10;
using namespace std;
const int mod = 998244353;

struct num{
    int l,r;
}a[N];

vector<int>mx(N),dp(N),date(N);

void solve() {
    int n;
    cin >> n;
    for(int i=2;i<=2*n+1;i++){
        int num;
        cin >> num;
        date[i]=num;
        if(a[num].l) a[num].r=i;
        else a[num].l=i;
    }
    a[0].l=1;
    a[0].r=2*n+2;
    date[1]=date[2*n+2]=0;
    for(int i=n;i>=0;i--){
        int l=a[i].l,r=a[i].r;
        dp[l-1]=0;
        for(int j=l;j<=r;j++){
            dp[j]=dp[j-1]+i;
            if(date[j]>i&&a[date[j]].l>l&&a[date[j]].r==j){
                dp[j]=max(dp[j],dp[a[date[j]].l-1]+mx[date[j]]);
            }
        }
        mx[i]=dp[r];
    }
    cout << mx[0];
}

signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
//    cin>>_;
    while (_--)solve();
}
posted @   yoez123  阅读(67)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示