zoukankan      html  css  js  c++  java
  • HDU6821 Set2(组合数+dp)

    DP的设计最重要的是找到合理的方案,如果求的是方案,那就要要求不重不漏。

    一般这种都跟组合数结合,一定要给组合数公式想到一个实际的物理意义,这样理解起来比较方便

    这题我确实不会,但是看题解觉得很牛逼,也很有道理,关键就是找到一个点能使得所有状态不重不漏

    一般都是考虑题目给的信息,很多情况下都是考虑集合中有什么数,然后以他为立足点,这是我的一些小思考

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<ll,ll> pll;
    const int N=2e5+10;
    const int M=2e6+10;
    const int inf=0x3f3f3f3f;
    const ll mod=998244353;
    int f[5010][5010];
    int n;
    int tmp[N],g[N];
    int cnt[N],sum[N];
    ll qmi(ll a,ll b){
        ll res=1;
        while(b){
            if(b&1){
                res=res*a%mod;
            }
            a=a*a%mod;
            b>>=1;
        }
        return res;
    }
    int C(int a,int b){
        if(a<b)
            return 0;
        return 1LL*tmp[a]*g[b]%mod*g[a-b]%mod;
    }
    void init(){
        int i,j;
        tmp[0]=1;
        for(int i=1;i<5000;++i) tmp[i]=1LL*tmp[i-1]*i%mod;
        g[4999]=qmi(tmp[4999],mod-2);
        for(int i=4998;i>=0;--i) g[i]=1LL*g[i+1]*(i+1)%mod;
    }
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        init();
        while(t--){
            int n,k;
            cin>>n>>k;
            int r=n%(k+1);
            int i,j;
            for(i=0;i<=n;i++){
                for(j=0;j<=n;j++){
                    f[i][j]=0;
                }
            }
            f[0][0]=1;
            if(r==0){
                for(i=1;i<n;i++){
                    cout<<0<<" ";
                }
                cout<<0;
                cout<<endl;
            }
            else if(n<=k){
                for(i=1;i<n;i++){
                    cout<<1<<" ";
                }
                cout<<1;
                cout<<endl;
            }
            else{
                for(i=0;i<n;i++){
                    for(j=0;j<=n;j++){
                        if(j+k+i-1<=n-r) f[i+1][j+k]=(f[i+1][j+k]+f[i][j])%mod;//i被当成最小数删除
                        if(j) f[i+1][j-1]=(f[i+1][j-1]+1ll*f[i][j]*j%mod)%mod;//被当作随机数删除,有j个位置可以选
                    }
                }
                ll tot=0;
                for(i=1;i<=n;i++){
                    int j=n-r-i+1;//还要选的数目
                    sum[i]=1ll*f[i-1][j]*C(n-i,j)%mod*tmp[j]%mod;//组合数+排列
                    tot=(tot+sum[i])%mod;//记录总方案数
                    cnt[i]=1ll*f[i-1][j]*C(n-i-1,j)%mod*tmp[j]%mod;//当x>i时 x存留,i提供的贡献
                }
                tot=qmi(tot,mod-2);
                ll res=0;
                for(i=1;i<=n;i++){
                    if(i!=n)
                        cout<<(sum[i]+res)*tot%mod<<" ";
                    else
                        cout<<(sum[i]+res)*tot%mod<<endl;
                    res=(res+cnt[i])%mod;
                }
            }
        }
        return 0;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    Three.js入门和搭建HelloWorld
    CentOS中使用Docker来部署Tomcat
    CentOS中使用Docker来部署Nginx
    Windows中通过bat定时执行命令和mysqldump实现数据库备份
    Geoserver在Linux上的安装(图文教程)
    Linux上怎样停止服务(jar包)、查看进程路径、关闭指定端口
    Java中怎样监测局域网内ip是否互通,类似ping
    Android和JS之间互相调用方法并传递参数
    Android中使用WebView加载本地html并支持运行JS代码和支持缩放
    ARC072C
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13608543.html
Copyright © 2011-2022 走看看