zoukankan      html  css  js  c++  java
  • E. Count The Blocks(找数学规律)

    (color{Red}{先说一下自己的歪解(找规律)})

    (n=1是答案是10)
    (n=2时答案是180)
    (n=3时模拟一下,很容易发现答案是2610 180 10)
    (然后我们大胆推测,n增加后,只有答案第一位发生变化,其余照搬n-1的答案)

    (然后发现n=3有1000个三位数,每个数有3个数字加起来是1000*3个数字)
    (刚才得出n=3时连续块长3有10种(0000,1111,...,9999),也就用掉了10*3个数字)
    (n=3时连续块长2有180种,也就用掉了180*2个数字)
    (所以易得连续块长1有3000-30-360=2610)

    (于是我们可以开始递推。)
    (递推方法是:当前总数字-当前所用数字=块长1的数字)
    要代码点我

    (color{Green}{--------------------无敌的分割线(●ˇ∀ˇ●)--------------------------})
    (color{Purple}{还有一种解法是组合数学的思想})

    (如当n=10我们怎么构造一个长度为L=3的块的数量呢?)

    (实际上这个长度为3的连续串可以从(10-3+1)个位置开头,分别是1、2、3...7、8)

    (如果从1和8开头,只需要相邻的一个元素和串不同其他随意,方案数是)

    [10(块可以是000,111等10种)*9(相邻元素有9种选法)*10^{n-L-1}(剩下n-L-1元素每个10种选法) ]

    (如果从2到7开头,那么需要相邻两个元素不同,方案数是)

    [10(块可以是000,111等10种)*9*9*(相邻元素有9种选法)*10^{n-L-2}(剩下n-L-2元素每个10种选法) ]

    下面引用博主EchoZQN的一段话

    (这个会不会出现重复呢?或者会不会少统计了呢?)

    (这两个看起来有矛盾的提问,其实就解决了这两个问题。)

    (因为我每一个位置只统计了一次,但是可能我假设的这个位置出现大小为 i 的块不止一个,所以才会有疑问会不会少统计了。)

    (同时因为每一个位置都统计了一次,所以可能会有两个位置,出现大小为 i 的块的数量及位置都相同,所以才会有疑问会不会重复统计了。)

    (确实有可能会出现 x 个位置,此时出现大小为 i 的块的数量及位置都相同)

    (但是每一次我只统计了一次,并没有乘以 x 这个数,所以不会重复,也不会丢掉一些数。)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=2e5+10;
    const int mod=998244353;
    typedef long long ll;
    ll dp[maxn],fac[maxn];
    int main()
    {
    	int n;
    	cin>>n;
    	dp[n]=10,dp[n-1]=180,fac[0]=1;
    	for(int i=1;i<=n;i++)	fac[i]=fac[i-1]*10%mod;
    	for(int i=n-2;i>=1;i--)
    	{
    		int l=n-i+1;// 
    		dp[i]=(l-2)*10*9*9*fac[n-i-2]%mod;
    		dp[i]+=2*10*9*fac[n-i-1];
    		dp[i]%=mod;
    	}
    	for(int i=1;i<=n;i++)	cout<<dp[i]<<" ";
    } 
    
  • 相关阅读:
    vue-if,vue-show,vue-for指令
    vue计算属性与监听器
    vue属性绑定和双向数据绑定
    C#将JSON文本转换成HttpResponseMessage数据行
    C#数据表(DataTable)转键值对集合
    C# .ToString()格式大全
    C#图片动画效果(旋转360度)异步
    C#利用鼠标绘图
    C#模拟键盘键操作
    C#显示和隐藏鼠标
  • 原文地址:https://www.cnblogs.com/iss-ue/p/12808073.html
Copyright © 2011-2022 走看看