zoukankan      html  css  js  c++  java
  • CF908G New Year and Original Order

    http://codeforces.com/problemset/problem/908/G

    题解

    考虑一个数的答案怎么算。
    比如说32214。
    我们求出大于等于1的数的个数,为5个,那么加上5*11111。

    大于等于2的数有4个,加上4*1111。

    大于等于3的有2个,加上3*111。

    大于等于4的有1个吗,加上4*1。

    最后发现等于12234,正好计算出了答案。

    所以我们直接设计状态(dp[i][j][k][0/1])表示前(i)位,大于等于数字(k)的有(j)个,是否卡边界。

    代码

    #include<bits/stdc++.h>
    #define N 702
    using namespace std;
    typedef long long ll;
    const int mod=1e9+7;
    char s[N];
    int n;
    int dp[N][N][10][2];
    inline ll rd(){
    	ll x=0;char c=getchar();bool f=0;
    	while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
    	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	return f?-x:x;
    }
    inline void MOD(int &x){x=x>=mod?x-mod:x;}
    inline void MOD(ll &x){x=x>=mod?x-mod:x;}
    int main(){
        scanf("%s",s+1);
        n=strlen(s+1);
        for(int i=1;i<=n;++i)s[i]-='0';
        for(int i=0;i<10;++i)dp[0][0][i][1]=1;
        for(int i=0;i<n;++i)
          for(int j=0;j<=i;++j)
            for(int k=1;k<=9;++k)
              for(int p=0;p<2;++p)if(dp[i][j][k][p])
    			for(int l=0;l<=9;++l){
                	if(p&&l>s[i+1])continue;
                	MOD(dp[i+1][j+(l>=k)][k][p&&(l==s[i+1])]+=dp[i][j][k][p]);
    			}
    	ll ans=0;
    	for(int i=1;i<10;++i){
    		ll nw=1;
    		for(int j=1;j<=n;++j)
    		  MOD(ans+=nw*(dp[n][j][i][0]+dp[n][j][i][1])%mod),MOD(nw=nw*10%mod+1);
    	}
    	cout<<ans;
    	return 0;
    }
    
    
  • 相关阅读:
    [代码]codeforces 150c Smart Cheater
    [存档]Young Tableau
    [转载][毁童年]种太阳
    [转载]教练,我也想再要一个同桌
    静夜
    CodeProject每日精选: Applications
    设计模式 装饰模式(Decorator) 精选经验合集
    槟榔味儿办公室
    盗不盗非常盗
    月末之周末
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/11099931.html
Copyright © 2011-2022 走看看