CF#764(div.3A~D)&&dp进阶

博客主要介绍了Codeforces第764场分站赛(A-D题)的解题思路,重点在于动态规划的应用。对于每道题目,详细阐述了题意、解题思路,并给出了AC代码。此外,还涉及了动态规划的进阶讨论,以括号问题为例,探讨最长正常序列的求解方法。
摘要由CSDN通过智能技术生成

CF#764(div.3A~D)&&dp进阶

CF#764(div.3)

Problem - A - Codeforces

题意

一个数列,每次操作可以使这个数列中的任何数加1,问最少经过多少次操作使这个数列的数相等

思路

只需要求极差便可

AC代码
#include<iostream>

using namespace std;

int t;
int a[60];
int n;
int main(){
    cin >> t;
    while (t--){
        cin >> n;
        int mmax = 0, mmin = 0;
        cin >> a[0];
        mmax = mmin = a[0];
        for (int i = 1; i < n; i++){
            cin >> a[i];
            if (a[i] > mmax) mmax = a[i];
            if (a[i] < mmin) mmin = a[i];
        }
        cout << mmax-mmin << endl;
    }
    return 0;
}

Problem - B - Codeforces

题意

给定三个正整数,选定其中一个数扩大x倍(x是正整数),使a,b,c成为等差数列

思路

等差数列则有a+c=2b,那么可以知道a+c|2b或2b-a|c或2b-c|a,依照这个作为判断条件,另外需要注意a+c,2b-a,2b-c都要是正整数才符合x>0的条件

AC代码
#include<iostream>

using namespace std;

int t, a, b, c;

int main(){
    cin >> t;
    while (t--){
        cin >> a >> b >> c;
        if ((a+c)%(2*b) == 0 &&(a+c)>0  || (2*b-a)% c == 0 && (2*b-a)>0  || (2*b-c) % a == 0 && (2*b-c)>0) cout << "YES";
        else cout << "NO";
        cout << endl;
    }
    return 0;
}

Problem - C - Codeforces

题意

给定一正整数数列,可以将这个数列中的任何数除2,要求最后得到1~n之间的所有数

思路

对数列中的每一个数进行判断,如果这个数在1~n中且之前遍历过的数中没有和它一样的,就遍历下一个,否则除2,如果一个数最后成了0,说明不可能达到要求,如果遍历完都符合要求,则可以

AC代码
#include<iostream>
#include<cstring>

using namespace std;
int t, n, a[60];
bool exist[60];
bool flag;

int main(){
    cin >> t;
    while (t--){
        cin >> n;
        flag = 0;
        memset(exist, 0, sizeof exist);
        for (int i = 0; i < n; i++) cin >> a[i];
        for (int i = 0; i < n; i++){
            while(1){
                if (a[i] == 0) {
                    cout << "NO" << endl;
                    flag = 1;
                    break;
                }
                if (a[i] > n) a[i] /= 2;
                else if (exist[a[i]]==true) a[i] /= 2;
                else{
                    exist[a[i]] = true;
                    break;
                }
            }
            if (flag) break;
        }
        if (!flag) cout << "YES" << endl;
            
    }
    return 0;
}

Problem - D - Codeforces

题意

给定一个字符串从中抽取k个回文字符串,并使最短的一个字符串的长度最大,求最短字符串的长度

思路

要使最短的字符串最长,则所有的字符串长度尽可能接近统计所有字母的个数,并统计个数为奇数的字母种数,先删去这些单个字符,剩下的都是成对的,然后分配,并且分配出的长度必须是偶数。最后再加入单个的字母

这个题我亏死了,写错了a的编码的值应该是97,可恶写题解的时候才发现,一定要牢记😂

AC代码
#include<iostream>
#include <string>
#include<cstring>
using namespace std;

int t, n, k;
string s;
int cal[30];

int main(){
    cin >> t;
    while (t--){
        memset(cal, 0, sizeof cal);
        int cnt = 0;
        cin >> n >> k;
        cin >> s;
        for (int i = 0; i < n; i++) cal[s[i]-97]++;
        for (int i = 0; i < 26; i++)
            if(cal[i] % 2 == 1) cnt++;
        n-=cnt;
        int res = n/k;
        if (res % 2 == 1) res -= 1;
        int only = n-res*k;
        if (only + cnt >= k) res++;
        cout << res << endl;
        

    }
    return 0;
}

#764(div.3)补完继续更新

dp进阶

A-Brackets

题意

给定一串()[]括号,求出这串括号的最长的正常序列

思路
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值