Codeforces Round 876 (Div. 2) A~D

A B C 就不说了,看懂题目就能AC。

A

#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include<vector>
#include<queue>
#include<map>
#include <unordered_map>
#include<set>
#include<tuple>
#include<numeric>
#include<stack>
using namespace::std;
typedef long long  ll;
inline char nc() {
    static char buf[1000000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
}
template <typename _Tp> inline void read(_Tp&sum) {
    char ch = nc(); sum = 0;
    while (!(ch >= '0'&&ch <= '9')) ch = nc();
    while (ch >= '0'&&ch <= '9') sum = (sum << 3) + (sum << 1) + (ch - 48), ch = nc();
}
inline __int128 read128(){
    __int128 x = 0, f = 1;
    char ch128 = getchar();
    while(ch128 < '0' || ch128 > '9'){
        if(ch128 == '-')
            f = -1;
        ch128 = getchar();
    }
    while(ch128 >= '0' && ch128 <= '9'){
        x = x * 10 + ch128 - '0';
        ch128 = getchar();
    }
    return x * f;
}
inline void print128(__int128 x){
    if(x < 0){
        putchar('-');
        x = -x;
    }
    if(x > 9)
        print128(x / 10);
    putchar(x % 10 + '0');
}
//struct dian{
//    double x,y;
//}A,B,C,D,E,F;//点
//cin>>A.x>>A.y>>B.x>>B.y>>C.x>>C.y>>D.x>>D.y>>E.x>>E.y>>F.x>>F.y;
//double len(dian x,dian y){
//    return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
//}//两点之间距离
//double xj(dian x,dian y,dian z){
//    x.x-=y.x;
//    x.y-=y.y;
//    z.x-=y.x;
//    z.y-=y.y;
//    return x.x*z.y-x.y*z.x;
//}//叉积
int n,t,m;
void wanyurukong(){
    cin>>n>>m;
    int jk=2;
    int kl=m+1;
    while (kl<n) {
        jk++;
        kl+=m;
    }
    cout<<jk<<"\n";
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(); cout.tie();
    cin>>t;
    while (t--) {
        wanyurukong();
    }
    //wanyurukong
    return 0;
}
 

B

#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include<vector>
#include<queue>
#include<map>
#include <unordered_map>
#include<set>
#include<tuple>
#include<numeric>
#include<stack>
using namespace::std;
typedef long long  ll;
inline char nc() {
    static char buf[1000000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
}
template <typename _Tp> inline void read(_Tp&sum) {
    char ch = nc(); sum = 0;
    while (!(ch >= '0'&&ch <= '9')) ch = nc();
    while (ch >= '0'&&ch <= '9') sum = (sum << 3) + (sum << 1) + (ch - 48), ch = nc();
}
inline __int128 read128(){
    __int128 x = 0, f = 1;
    char ch128 = getchar();
    while(ch128 < '0' || ch128 > '9'){
        if(ch128 == '-')
            f = -1;
        ch128 = getchar();
    }
    while(ch128 >= '0' && ch128 <= '9'){
        x = x * 10 + ch128 - '0';
        ch128 = getchar();
    }
    return x * f;
}
inline void print128(__int128 x){
    if(x < 0){
        putchar('-');
        x = -x;
    }
    if(x > 9)
        print128(x / 10);
    putchar(x % 10 + '0');
}
//struct dian{
//    double x,y;
//}A,B,C,D,E,F;//点
//cin>>A.x>>A.y>>B.x>>B.y>>C.x>>C.y>>D.x>>D.y>>E.x>>E.y>>F.x>>F.y;
//double len(dian x,dian y){
//    return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
//}//两点之间距离
//double xj(dian x,dian y,dian z){
//    x.x-=y.x;
//    x.y-=y.y;
//    z.x-=y.x;
//    z.y-=y.y;
//    return x.x*z.y-x.y*z.x;
//}//叉积
int n,t,m;
struct we{
    int x,y;
}c[200005];
bool cmp(we a,we b){
    if (a.x==b.x) {
        return a.y>b.y;
    }
    return a.x<b.x;
}
void wanyurukong(){
    cin>>n;
    for (int i=1; i<=n; i++) {
        cin>>c[i].x>>c[i].y;
    }
    sort(c+1, c+1+n,cmp);
    c[0].x=c[0].y=0;
    int fx=0;
    ll na=0;
    for (int i =1; i<=n; i++) {
        if (c[i].x!=c[i-1].x) {
            fx=c[i].x-1;
            na+=c[i].y;
            continue;
//            cout<<c[i].x<<" "<<c[i].y<<"\n";
        }
        if (fx) {
            fx--;
            na+=c[i].y;
//            cout<<c[i].x<<" "<<c[i].y<<"\n";
        }
    }
    cout<<na<<"\n";
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(); cout.tie();
    cin>>t;
    while (t--) {
        wanyurukong();
    }
    //wanyurukong
    return 0;
}
 

C

#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include<vector>
#include<queue>
#include<map>
#include <unordered_map>
#include<set>
#include<tuple>
#include<numeric>
#include<stack>
using namespace::std;
typedef long long  ll;
inline char nc() {
    static char buf[1000000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
}
template <typename _Tp> inline void read(_Tp&sum) {
    char ch = nc(); sum = 0;
    while (!(ch >= '0'&&ch <= '9')) ch = nc();
    while (ch >= '0'&&ch <= '9') sum = (sum << 3) + (sum << 1) + (ch - 48), ch = nc();
}
inline __int128 read128(){
    __int128 x = 0, f = 1;
    char ch128 = getchar();
    while(ch128 < '0' || ch128 > '9'){
        if(ch128 == '-')
            f = -1;
        ch128 = getchar();
    }
    while(ch128 >= '0' && ch128 <= '9'){
        x = x * 10 + ch128 - '0';
        ch128 = getchar();
    }
    return x * f;
}
inline void print128(__int128 x){
    if(x < 0){
        putchar('-');
        x = -x;
    }
    if(x > 9)
        print128(x / 10);
    putchar(x % 10 + '0');
}
//struct dian{
//    double x,y;
//}A,B,C,D,E,F;//点
//cin>>A.x>>A.y>>B.x>>B.y>>C.x>>C.y>>D.x>>D.y>>E.x>>E.y>>F.x>>F.y;
//double len(dian x,dian y){
//    return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
//}//两点之间距离
//double xj(dian x,dian y,dian z){
//    x.x-=y.x;
//    x.y-=y.y;
//    z.x-=y.x;
//    z.y-=y.y;
//    return x.x*z.y-x.y*z.x;
//}//叉积
int n,t,m;
int a[100005];
void wanyurukong(){
    cin>>n;
    for (int i=1; i<=n; i++) {
        cin>>a[i];
    }
    if (a[n]==1) {
        cout<<"NO\n";return;
    }
    if (n==1) {
        if (a[1]==0) {
            cout<<"YES\n";
            cout<<"0\n";
        }
        else{
            cout<<"NO\n";
        }
        return;
    }
    cout<<"YES\n";
    vector<int>fx;
    int jk=0;
    for (int i =n; i>=1; i--) {
        if (a[i]==0) {
            fx.push_back(0);
        }
        if (a[i]==1) {
            jk++;
            if (a[i-1]==0) {
                fx.push_back(jk);
                jk=0;
            }
            else
            {
                fx.push_back(0);
            }
        }
    }
    for (int i =0; i<fx.size(); i++) {
        cout<<fx[i]<<" ";
    }
    cout<<"\n";
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(); cout.tie();
    cin>>t;
    while (t--) {
        wanyurukong();
    }
    //wanyurukong
    return 0;
}
 

D

这道题我们不难看出,如果花费最少,我们需要找最长上升子序列,然后基于其来,不断维护其他的上升序列,然后中间分段。思路很简单,但是代码不是很好写,我们用dp来转移。具体的细节原理,写到了代码注释里面,可以仔细思考一下。

#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include<vector>
#include<queue>
#include<map>
#include <unordered_map>
#include<set>
#include<tuple>
#include<numeric>
#include<stack>
using namespace::std;
typedef long long  ll;
inline char nc() {
    static char buf[1000000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
}
template <typename _Tp> inline void read(_Tp&sum) {
    char ch = nc(); sum = 0;
    while (!(ch >= '0'&&ch <= '9')) ch = nc();
    while (ch >= '0'&&ch <= '9') sum = (sum << 3) + (sum << 1) + (ch - 48), ch = nc();
}
inline __int128 read128(){
    __int128 x = 0, f = 1;
    char ch128 = getchar();
    while(ch128 < '0' || ch128 > '9'){
        if(ch128 == '-')
            f = -1;
        ch128 = getchar();
    }
    while(ch128 >= '0' && ch128 <= '9'){
        x = x * 10 + ch128 - '0';
        ch128 = getchar();
    }
    return x * f;
}
inline void print128(__int128 x){
    if(x < 0){
        putchar('-');
        x = -x;
    }
    if(x > 9)
        print128(x / 10);
    putchar(x % 10 + '0');
}
//struct dian{
//    double x,y;
//}A,B,C,D,E,F;//点
//cin>>A.x>>A.y>>B.x>>B.y>>C.x>>C.y>>D.x>>D.y>>E.x>>E.y>>F.x>>F.y;
//double len(dian x,dian y){
//    return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
//}//两点之间距离
//double xj(dian x,dian y,dian z){
//    x.x-=y.x;
//    x.y-=y.y;
//    z.x-=y.x;
//    z.y-=y.y;
//    return x.x*z.y-x.y*z.x;
//}//叉积
int n,t;
int a[505];
ll dp[505][505];
ll ans[505];
void wanyurukong(){
    cin>>n;
    for (int i =1; i<=n; i++) {
        cin>>a[i];
    }
    for (int i =0; i<=n; i++) {
        ans[i]=-100;
        for (int j =0; j<=n; j++) {
            dp[i][j]=-10000;
        }
    }
    dp[0][0]=0;//初始化
    //以i结尾,有j段非最长上升子序列
    for (int i =1; i<=n; i++) {
        for (int j =0; j<=(i+1)/2; j++) {
            if (a[i-1]<a[i]) {
                dp[i][j]=max(dp[i][j], dp[i-1][j]+1);
                //上一个以i-1结尾最大,如果继续上升,则转移+1
            }
            if (!j) {
                continue;
            }
            //中间断续
            for (int  k=0; k<i-1; k++) {
                if (a[k]<a[i]) {
                    dp[i][j]=max(dp[i][j], dp[k][j-1]+1);
                    //每次j-1,从i后面中间中断一次,更新最大值,每次至少断一个数字
                    //后续j++。前边断过的变大的值不会再被更新,而且每次断续是连续的,如果继续并且有更大价值更新,那么一定不是一段,所以以此来推断不断断续来更新最大值的值
                }
            }
            
        }
    }
    for (int j=0; j<=n; j++) {
        for (int i =1; i<=n; i++) {
            if (i==n) {//i==n是最后一位,所以不用再考虑后续数字的情况
                ans[j]=max(ans[j], dp[i][j]);
            }
            else
            {   //考虑后续数字,所以j-1
                ans[j]=max(ans[j], dp[i][j-1]);
            }
        }
        //简单的前值最大值转移,小段可优,则大段不需再多分割
        ans[j]=max(ans[j], ans[j-1]);
    }
//     debug
//    for (int i=0; i<=n;i++) {
//        for (int j =0; j<=n; j++) {
//            cout<<dp[i][j]<<" ";
//        }
//        cout<<"\n";
//    }
//    for (int i =1; i<=n; i++) {
//        cout<<ans[i]<<" ";
//    }
//    cout<<"\n";
//    return;
    for (int i =1; i<=n; i++) {
        cout<<n-ans[i]<<" ";
    }
    cout<<"\n";
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(); cout.tie();
    cin>>t;
    while (t--) {
        wanyurukong();
    }
    //wanyurukong
    return 0;
}
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值