• Codeforces 每日一练 706C+575H+15C


    欢迎进群互% :1042591643

    706C Hard problem

    传送门
    镜像
    题意:给定n个字符串,反转每个字符串有代价c[i],求使得所有字符串按字典序排列所需的最小代价,如果不可能,输出-1;
    看一眼数据范围和题意大概就猜出来是用二维了,0代表不反转,1代表反转,转移方程也很容易就可以写出来

    dp[i][1]=min(dp[i-1][0]+c[i],dp[i-1][1]+c[i]);
    dp[i][0]=min(dp[i-1][0],dp[i-1][1]);        
    

    如果该情况合法就去转移,但是要注意,如果某种情况不合法,那么该情况就不能用于后面的转移了,因此我开了另一个数组去记录是否合法,同时记录是否发生了转移,如果没有,说明无法满足题意,直接输出-1;

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define maxn 100005
    #define eps 1e-4
    #define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    #pragma GCC optimize(2)
    #define lowbit(x) ((x)&-(x))
    #define ull unsigned long long
    #define db double
    #define ld long double
    #define mod 1000000007
    string s[maxn],t[maxn];
    ll c[maxn];
    ll dp[maxn][2];
    int vis[maxn][2];
    signed main(){
        IOS
        int n;
        cin>>n;
        for (int i = 1; i <=n ; ++i) {
            cin>>c[i];
            dp[i][0]=dp[i][1]=9223372036854775800;
        }
        for (int i = 1; i <=n ; ++i) {
            cin>>s[i];
            reverse(s[i].begin(),s[i].end());
            t[i]=s[i];
            reverse(s[i].begin(),s[i].end());
        }
        dp[1][0]=0;
        dp[1][1]=c[1];
        vis[1][1]=1;
        vis[1][0]=1;
        for (int i = 2; i <=n ; ++i) {
            int fl=0;
            if(t[i]>=s[i-1]&&vis[i-1][0]==1){
                vis[i][1]=1;
                dp[i][1]=min(dp[i][1],dp[i-1][0]+c[i]);
                fl=1;
            }
            if(t[i]>=t[i-1]&&vis[i-1][1]==1){
                vis[i][1]=1;
                dp[i][1]=min(dp[i][1],dp[i-1][1]+c[i]);
                fl=1;
            }
            if(s[i]>=s[i-1]&&vis[i-1][0]==1){
                vis[i][0]=1;
                dp[i][0]=min(dp[i][0],dp[i-1][0]);
                fl=1;
            }
            if(s[i]>=t[i-1]&&vis[i-1][1]==1){
                vis[i][0]=1;
                dp[i][0]=min(dp[i][0],dp[i-1][1]);
                fl=1;
            }
            if(!fl){
                cout<<"-1";
                return 0;
            }
        }
        cout<<min(dp[n][1],dp[n][0]);
        return 0;
    }
    
    

    575H Bots

    传送门
    镜像
    题意:两个机器人分别可以走0-n步,且分别会把走过的步数染成红色或蓝色,求所有的染色情况数。
    想出答案并不难,明显答案应该是i=0nj=0nCi+jisum_{i=0}^nsum_{j=0}^nC_{i+j}^{i},难点在化简求值,首先关于组合数有恒等式Cn+1m+1=Cnm+1+Cnm C_{n+1}^{m+1}=C_{n}^{m+1}+C_{n}^{m}
    根据这个恒等式可以将第一个求和化简为Ci+n+1i+1C_{i+n+1}^{i+1},之后在化简第二个求和时,先加上Cn+21C_{n+2}^{1},就可以把答案化简为C2n+2n+1+Cn+11C_{2*n+2}^{n+1}+C_{n+1}^{1},之后减去Cn+21C_{n+2}^{1},则答案即为C2n+2n+11C_{2*n+2}^{n+1}-1的值取模。
    卢卡斯定理套个板子就OK

    #include <bits/stdc++.h>
    #define mod 1000000007
    using namespace std;
    typedef long long ll;
    ll mulit(ll a,ll b,ll m){
        ll ans=0;
        while(b){
            if(b&1) ans=(ans+a)%m;
            a=(a<<1)%m;
            b>>=1;
        }
        return ans;
    }
    ll quick_mod(ll a,ll b,ll m){
        ll ans=1;
        while(b){
            if(b&1){
                ans=mulit(ans,a,m);
            }
            a=mulit(a,a,m);
            b>>=1;
        }
        return ans;
    }
    ll comp(ll a,ll b,ll m){
        if(a<b) return 0;
        if(a==b) return 1;
        if(b>a-b) b=a-b;
        ll ans=1,ca=1,cb=1;
        for(int i=0;i<b;i++){
            ca=ca*(a-i)%m;
            cb=cb*(b-i)%m;
        }
        ans=ca*quick_mod(cb,m-2,m)%m;
        return ans;
    }
    ll lucas(ll a,ll b,ll m){
        ll ans=1;
        while(a&&b){
            ans=(ans*comp(a%m,b%m,m))%m;
            a/=m;
            b/=m;
        }
        return ans;
    }
    int main()
    {
        ll a,b,m,n;
        cin>>n;
        ll ans=lucas(2*n+2,n+1,mod)-1;
        ans%=mod;
        cout<<ans;
        return 0;
    }
    

    15C Industrial Nim

    直接贴大佬的题解啦
    写的比我好多了Orz
    传送门

  • 相关阅读:
    利用npm 安装删除模块
    C#比较类/接口、Dictionary 排序
    关于二叉树的一些基本知识
    关于前端JS的一些常用方法和知识
    组装Json数据的一种简单办法(不用Stringbuilder方法)
    windows环境下Kubernetes及Docker安装(那些坑)
    七夕给自己的礼物-上线排盘小程序
    Asp.net 自定义CustomerSession 存放到Redis中
    CodeTimer 代码性能计数器
    我虽码农,亦不搬砖
  • 原文地址:https://www.cnblogs.com/Bazoka13/p/12635505.html
Copyright © 2020-2023  润新知