zoukankan      html  css  js  c++  java
  • AtCoder AGC009E Eternal Average (DP)

    题目链接

    https://atcoder.jp/contests/agc009/tasks/agc009_e

    题解

    又被劝退了。。。
    第一步转化非常显然: 就等价于一开始有一个数(1), 有(frac{n+m-1}{k-1})次机会每次选择一个数把它变成(k)个原来的(frac{1}{k}), 最后从(n+m)个数中选出(m)个,问能选出多少不同的数。
    然后考虑化成(k)进制小数,假设最后形成的数是(d_1,d_2,...,d_{n+m}), 则(sum^{n+m}_{i=1} d_i=1).
    一个(d)进制小数可以被表示成(m)(k)的负整数次幂之和当且仅当其每一位数值之和不超过(m)且和(m)((k-1))同余。(显然)
    但同时还要保证(1)可以被表示成((n+m))(k)的负整数次幂之和,且包含这(m)个数。那么就可以转化成(1)减这个小数可以被表示成(n)(k)的负整数次幂之和。(行吧我就这一步没想出来……自闭了啊……)
    所以最后也就是要计算有多少个序列(a_1,a_2,...,a_l (1le lle frac{n+m-1}{k-1})), 满足(0le a_ile k-1, a_l>0, sum^l_{i=1}a_ile m,sum^l_{i=1}a_iequiv m(mod k-1), sum^l_{i=1}k-1-a_ile n-1, sum^l_{i=1}k-1-a_iequiv n-1(mod k-1)), 直接dp即可。时间复杂度(O((n+m)k)).

    代码

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<cassert>
    #define llong long long
    using namespace std;
    
    const int N = 4e3;
    const int P = 1e9+7;
    llong dp[N+3][N+3],sdp[N+3][N+3];
    int n1,n2,m,len;
    llong ans;
    
    int main()
    {
    	scanf("%d%d%d",&n1,&n2,&m); len = (n1+n2-1)/(m-1);
    	dp[0][0] = 1ll; for(int j=0; j<=n2; j++) sdp[0][j] = 1;
    	for(int i=1; i<=len; i++)
    	{
    		for(int j=0; j<=n2; j++)
    		{
    			if(j>=m) {dp[i][j] = (sdp[i-1][j]-sdp[i-1][j-m]+P)%P;}
    			else {dp[i][j] = sdp[i-1][j];}
    			if((n2-j)%(m-1)==0 && i*(m-1)-j<=n1-1 && (n1-1-i*(m-1)+j)%(m-1)==0) {ans = (ans+dp[i][j]-dp[i-1][j]+P)%P;}
    		}
    		sdp[i][0] = dp[i][0]; for(int j=1; j<=n2; j++) sdp[i][j] = (sdp[i][j-1]+dp[i][j])%P;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Python 包的概念
    EXCEL基础篇(二)
    EXCEL基础篇(一)
    JavaScript(四)Bom
    JavaScript(三)Dom查找、设置标签属性及内容、绑定事件
    erlang并发编程(二)
    OTP&ETS
    erlang中http请求
    erlang证书加密
    erlang并发编程
  • 原文地址:https://www.cnblogs.com/suncongbo/p/11519281.html
Copyright © 2011-2022 走看看