Codeforces Round #459 (Div. 2)题解

补题

codeforces 918C

题意

给定一个含有通配符?()的字符串,问有多少子串是括号匹配的

解题思路

首先考虑不用栈求括号匹配的方法:

bool solve(char* s)
{
    int top=0;
    for (int i=0;i<strlen(s);i++)
    {
        if(s[i]==‘(‘)   top++;
        else top--;
        if(top<0)   return false;
    }
    return top==0;
}

由于在使用栈的括号匹配算法中,栈内是不存在)的,所以不难证明这个算法和使用栈的括号匹配算法是等价的

我们维护一个\(top\)值的上确界\(sup\)和下确界\(inf\),如果维护过程\(inf<0\),那么对于所有后续的串的合法通配方案,都至少需要让这段的一个?变成(,我们不妨让下界变成\(0\)。那么每次串长度为偶数并且区间存在能组成\(0\)的方案(即\(inf=0\))即说明子串是可以括号匹配的

复杂度\(O(n^2)\)

AC代码

#include <bits/stdc++.h>
using namespace std;
char str[5020];
int main()
{
    scanf("%s",&str);
    int len=strlen(str);
    int ans=0;
    for (int i=0;i<len;i++)
    {
        int sup=0,inf=0;
        for (int j=i;j<len;j++)
        {
            if(str[j]==‘(‘) inf++,sup++;
            else if(str[j]==‘)‘)    sup--,inf--;
            else inf--,sup++;
            if(sup<0)   break;
            if(inf<0)   inf=0;
            if((j-i+1)%2==0&&inf==0)    ans++;
        }
    }
    printf("%d\n",ans);
}

codeforces 918D

题意

给定一个有向无环图(\(DAG\)) \(G\),边上有用字母表示的权值,权值的大小关系由\(ASCII\)码决定。玩家\(A\)和\(B\)进行博弈,\(A\)先手,\(B\)后手,两名玩家各有一个棋子,每一轮将棋子从图上的一个点沿着有向边移动到另一个点,随后移动权转给另一名玩家。

规定:每一轮走的边的权值必须大于等于上一次走的权值

胜利条件:当有一名玩家无法走时,另一名玩家获得胜利

输出\(n\)行\(n\)列,其中\(n\)为图的点数,假设两名玩家都是绝对理性的,第\(i\)行\(j\)列输出获胜的玩家(\(A/B\))

\(n \le 100\)

解题思路

对于这类的组合游戏,我们可以知道:

一个状态是必败状态当且仅当它的所有后继都是必胜状态或者没有后继

一个状态是必胜状态当且仅当它至少又一个后继是必败状态

那么对于此题,我们不妨用dp[u][v][c]表示\(A\)在\(u\),\(B\)在\(v\),上一轮移动边的权值为\(c\)的状态,如果存在边\(e\),并且权值\(\ge c\),那么它可以转移到dp[v][e.to][e.c](等效于从\(B\)开始先手)

进而根据上面的准则判断这个状态是否是必胜/败状态即可,答案是dp[i][j][0]

实现上可以使用记忆化搜索

粗略估计最坏情况每次都要遍历一次图,复杂度\(O(n^4)\),实际的上界大概要再低一些,因为不可能每次都要遍历图

AC代码

#include <bits/stdc++.h>
using namespace std;
const int maxn=102;
struct edge
{
    int to,cost;
    edge(int t,int c):to(t),cost(c){
    }
    bool operator < (const edge &rhs) const
    {
        return cost<rhs.cost;
    }
};
vector <edge> G[maxn];
int dp[maxn][maxn][28];
int solve(int u,int v,int c)
{
    if(dp[u][v][c]!=-1)
        return dp[u][v][c];
    dp[u][v][c]=0;
    for (edge &e: G[u])
    {
        if(e.cost<c)    continue;
        dp[u][v][c]|=(!solve(v,e.to,e.cost));
    }
    return dp[u][v][c];
}
int main()
{
    int m,n;
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++)
    {
        int u,v;
        char c;
        scanf("%d%d",&u,&v);
        cin>>c;
        G[u].push_back(edge(v,c-‘a‘+1));
    }
    memset(dp,-1,sizeof(dp));
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=n;j++)
            if(solve(i,j,0))
                printf("A");
            else
                printf("B");
        puts("");
    }
}

原文地址:https://www.cnblogs.com/falseangel/p/8394887.html

时间: 2024-10-04 21:44:58

Codeforces Round #459 (Div. 2)题解的相关文章

Codeforces Round #262 (Div. 2) 题解

A. Vasya and Socks time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Vasya has n pairs of socks. In the morning of each day Vasya has to put on a pair of socks before he goes to school. When

Codeforces Round #FF (Div. 2) 题解

比赛链接:http://codeforces.com/contest/447 A. DZY Loves Hash time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output DZY has a hash table with p buckets, numbered from 0 to p?-?1. He wants to insert n 

Codeforces Round #259 (Div. 2) 题解

A. Little Pony and Crystal Mine time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Twilight Sparkle once got a crystal from the Crystal Mine. A crystal of size n (n is odd; n?>?1) is an n?×?n 

Codeforces Round #177 (Div. 2) 题解

[前言]咦?现在怎么流行打CF了?于是当一帮大爷在执着的打div 1的时候,我偷偷的在刷div 2.至于怎么决定场次嘛,一般我报一个数字A,随便再拉一个人选一个数字B.然后开始做第A^B场.如果觉得机密性不高,来点取模吧.然后今天做的这场少有的AK了.(其实模拟赛只做完了4题,最后1题来不及打了) 等等,话说前面几题不用写题解了?算了,让我难得风光一下啦. [A] A. Polo the Penguin and Segments time limit per test 2 seconds mem

Codeforces Round #459 (Div. 2) C 思维,贪心 D 记忆化dp

Codeforces Round #459 (Div. 2) C. The Monster 题意:定义正确的括号串,是能够全部匹配的左右括号串. 给出一个字符串,有 (.). ? 三种字符, ? 可以当作 ( 可 ) . 问这个字符串有多少个子串是正确的括号串. tags:好考思维,想不到.. 预处理出每个字符向左向右最多可以匹配到哪里,再 O(n*n) 枚举所有区间,看是否符合条件. // C #include<bits/stdc++.h> using namespace std; #pra

Codeforces Round #534 (Div. 2)题解

Codeforces Round #534 (Div. 2)题解 A. Splitting into digits 题目大意 将一个数字分成几部分,几部分求和既是原数,问如何分可以使得分出来的各个数之间的差值尽可能小 解题思路 将n分成n个1相加即可 AC代码 #include<cstring> #include<string> #include<iostream> #include<cstdio> using namespace std; int main

Codeforces Round #561 (Div. 2) 题解

Codeforces Round #561 (Div. 2) 题解 题目链接 A. Silent Classroom 水题. Code #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 105; int n; char s[N], t[N]; int main() { cin >> n; for(int i = 1; i <= n; i++) { scanf(&q

Codeforces Round #608 (Div. 2) 题解

目录 Codeforces Round #608 (Div. 2) 题解 前言 A. Suits 题意 做法 程序 B. Blocks 题意 做法 程序 C. Shawarma Tent 题意 做法 程序 D. Portals 题意 做法 程序 E. Common Number 题意 做法 程序 结束语 Codeforces Round #608 (Div. 2) 题解 前言 题目链接:仅仅只是为了方便以题目作为关键字能查找到我的题解而已(逃 Codeforces 1271A Codeforce

Codeforces Round #617 (Div. 3) 题解

目录 Codeforces Round #617 (Div. 3) 题解 前言 A. Array with Odd Sum 题意 做法 程序 B. Food Buying 题意 做法 程序 C. Yet Another Walking Robot 题意 做法 程序 D. Fight with Monsters 题意 做法 程序 E1. String Coloring (easy version) 题意 做法 程序 E2. String Coloring (hard version) 题意 做法