zoukankan      html  css  js  c++  java
  • Codeforces 1142D(dp)

    题目传送

    先给出设计dp的结论:

    dp[i][j]:以第i个位置、以rankj的数拓展出去的方案数。意会一下,我实在想不好语言……

    其中所谓rankj=真·rank%11

    找到拓展的规律,转移也就顺理成章了。不妨先看1~9拓展到的二位数里有哪些是合法拓展:

    [Rank1\%11=1:所以数字1 ightarrow10 ]

    [Rank2\%11=2:所以数字2 ightarrow20 21 ]

    […… ]

    [Rank9\%11=9:所以数字9 ightarrow90 91 92 93 94 95 96 97 98 ]

    再拓展到三位数找找规律:

    [Rank10\%11=10:所以数字10 ightarrow100 101......109 ]

    [Rank11\%11=0:所以数字20 ightarrow无法拓展 ]

    [Rank12\%11=1:所以数字21 ightarrow210 ]

    [Rank13\%11=2:所以数字30 ightarrow300 301 ]

    可以看出能够拓展的个数也是按照%11的规则循环的,所以我们要在rank之间做转移(以下说rank都是%11以后的rank,不%11的话状态太多)

    规律:
    1.当前rank转移过去的数字,个位数字一定小于rank

    2.如果我们每11个合法数分为一组,则这11个数将拓展出新的55个数(注意这是会%11 = 0的),也就意味着$$0 1 2 3 4 5 6 7 8 9 10 $$$$20 21 30 31 32 40 41 42 43 50 51$$$$……$$每11个数会拓展出55个新数(反正0也不贡献,可加)。
    现在举例:$$51排名j为10;$$$$51拓展出的 ightarrow510的排名j'将为10$$怎么算的呢?更普遍化地来说,当前数字排名为j时,假如它向后拓展一位,然后个位数字为d,则新数字排名为$$(frac{j(j-1)}{2}+(d+1)+(10-1)) % 11$$这样理解,比如51要拓展到512,$$frac{109}{2}是20~50拓展出的三位数个数$$$$d+1=2+1是510~512$$$$10-1是1~9的rank加上去$$
    对于第一条,发现0~10拓展出55个数(我们一开始就列了),所以0~10拓展出的数目%11后为0并不影响rank。所以只计算20~50的即可。其他也是同理,因为我们是11个一组的;
    第二条不解释;
    对于第三条,我们只加了0~10拓展的数为开始的,却没加1~10(这时就别算0了),然后为啥-1呢?因为0~10拓展的数里本来就有个10了,10算了两遍。也就相当于把1~9加上。

    懂了以上式子以后就可以直接看代码了:

    #include <cstdio>
    #include <cstring>
    
    const int maxn = 1e5 + 5;
    char S[maxn];
    __int64_t ans, dp[maxn][15];//以第i个位置、以rankj的数拓展出去的方案数
    
    int main() {
    	scanf("%s", S + 1);
    	int len = strlen(S + 1);
    
    	for (int i = len; i; --i) {
    		int d = S[i] - '0';
    
    		for (int j = 0; j <= 10; ++j) {
    			dp[i][j] = 1;//自己独立成一个方案
    			if (i < len) {
    				int t = S[i + 1] - '0';
    				if (j > t) {//与后面联合,当前rank只会转移到更小的数字
    					dp[i][j] += dp[i + 1][(j * (j - 1) / 2 + t + 10) % 11];//事实上只有两位数的转移也可以直接打表
    				}
    			}	
    		}
    
    		if (d)	ans += dp[i][d];//题目限制从1~9为起点
    	}
    
    	printf("%lld
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    poj 1753 -- Flip Game
    hdu 2209 -- 翻纸牌游戏
    文件系统的挂载与卸载挂载
    我的vim配置(一)
    Poj 3687 -- Labeling Balls
    主动激发“onclick”事件;prompt
    this
    函数嵌套
    调用函数时传递的实参个数arguments.length; ,函数定义时的形参个数sum.length
    回调函数,用户定义的排序规则
  • 原文地址:https://www.cnblogs.com/AlphaWA/p/10665100.html
Copyright © 2011-2022 走看看