zoukankan      html  css  js  c++  java
  • 牛客【2021寒假集训营第一场】A-串

    【2021寒假集训营第一场】A-串

    dp,容斥原理,快速幂

    传送门

    这个题目就是容斥原理的应用,关键是弄明白长度为i的字符串根据us分为几种

    长度为i的字符串主要分为三种:

    • 不含u的
    • 含u不含us的
    • 含us的

    这三种加起来就是全集

    解法一:

    使用(f[i])表示长度为i的含有us的字符串

    可以分为以下两种:

    • 前i-1个字符串含有us,那么第i个字符可以是26个字母中任意一个:(f[i] += f[i-1]*26)
    • 前i-1个字符含有u,但是不含有us,那么第i个字符只需要填一个i即可:(f[i] += 26^{i-1} -25^{i-1} - f[i-1])
      • 前i-1个字符含有u(即全部组合减去不含有u的组合):(26^{i-1} -25^{i-1})
      • 不含有us,上面的结果减去含有us的即可,(26^{i-1} -25^{i-1}-f[i-1])

    所以结果就是(f[i] = 26^{i-1} -25^{i-1} + 25* f[i-1])

    注意这里计算幂的时候要使用到快速幂算法,其中还需要取模运算

    ac代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mod = 1e9+7;
    int n;
    ll f[2000010];
    int q_pow(ll a, ll n)
    {
    	ll ans = 1;
        ll tot = a; // 这里必须是ll类型,不然就会出错!因为tot是指数上升的 
    	while(n){
    		if(n&1) ans = (ans*tot)%mod;
    		tot = (tot*tot)%mod;
    		n>>=1;
    	}
    	return ans%mod;
    }
    
    int main()
    {
    	cin >> n;
    	f[2] = 1;
    	for(int i=3; i<=n; ++i){
    		f[i] = (q_pow(26, i-1) - q_pow(25, i-1) + f[i-1]*25 % mod + mod)%mod; // 括号里面+mod是为了防止负数 
    	}
    	ll ans = 0;
    	for(int i=2; i<=n; ++i){
    		ans = (ans+f[i])%mod;
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    

    解法二:

    将一个长为i的字符串分为三类,并用(f[i][0/1/2])表示

    • (f[i][0])表示的是长度为i,不含有u的字符串
    • (f[i][1])表示的是长度为i,含有u,不含有us的字符串
    • (f[i][2])表示的是含有us的字符串

    则可以得到以下关系:

    1. (f[i][0] = 25*f[i-1][0]);即前i个不含有u的字符串为前i-1个不含u的字符串,末尾添加一个非u字符
    2. (f[i][1] = f[i-1][0] + f[i-1][1]*25);如1,根据公式理解即可
    3. (f[i][2] = f[i-1][1] + f[i-1][2]*26);如1,根据公式理解即可

    ac 代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mod = 1e9+7;
    int n;
    ll f[1000010][3];
    int main()
    {
    	cin >> n;
    	f[2][0] = 25*25; 
    	f[2][1] = 50; 
    	f[2][2] = 1;
    	for(int i=3; i<=n; ++i){
    		f[i][0] = f[i-1][0]*25%mod;
    		f[i][1] = (f[i-1][0] + 25*f[i-1][1])%mod;
    		f[i][2] = (f[i-1][1] + 26*f[i-1][2])%mod;
    	} 
    	ll ans = 0;
    	for(int i=2; i<=n; ++i){
    		ans = (ans+f[i][2])%mod;
    	}
    	cout << ans;
    	return 0;
    }
    
  • 相关阅读:
    .Net转Java自学之路—SpringMVC框架篇九(拦截器)
    .Net转Java自学之路—SpringMVC框架篇八(RESTful支持)
    移动端高清适配、布局开发解决方案
    Webpack+Gulp+React+ES6开发
    gulp使用gulp-file-include将header/footer引入页面
    git在window与linux的换行符问题
    文件(图片)上传组件
    ie8、9跨域上传文件(图片)
    移动端rem布局背景图片使用以及sprite雪碧图
    iOS/Android 浏览器(h5)及微信中唤起本地APP
  • 原文地址:https://www.cnblogs.com/VanHa0101/p/14406832.html
Copyright © 2011-2022 走看看