首页 > 其他 > 详细

HEOI2014 平衡

时间:2018-08-09 22:45:27      阅读:182      评论:0      收藏:0      [点我收藏+]

暑期的训练发现DP不行,万年写不对系列已经上线

这题其实类似dp问题中的整数划分问题

考虑用dp[i][j]表示分成了不同的i个数,和为j

考虑转移dp[i][j]=dp[i-1][j-i]+dp[i][j-i]

考虑意义,dp[i][j-i]表示给当前i组全部都加上1

dp[i-1][j-i]表示考虑加入一个1,为了防止没有重复的数,所以先给原来的i-1个数都加1

那如果当前dp[i][j]有些方案没有1呢?我们发现根本不会少算,它一定会在其他dp值里面算到

最后枚举一下两边分别删几个就行了

注意特判K=1和取0的情况即可

代码:

#include<bits/stdc++.h>
using namespace std;
int dp[15][100005],T,n,k,Mod;
int main(){
    scanf("%d",&T);
    while (T--){
        scanf("%d%d%d",&n,&k,&Mod);
        dp[0][0]=1;
        for (int i=1;i<=k;i++){
            for (int j=i;j<=n*k;j++){
                dp[i][j]=1ll*(dp[i-1][j-i]+dp[i][j-i])%Mod;
                if (j>n) dp[i][j]-=dp[i-1][j-n-1];
                if (dp[i][j]<0) dp[i][j]+=Mod;
            }
        }int ans=0;if(k==1){puts("1");continue;}
        for (int i=1;i<k;i++)
            for (int j=i;j<=n*k;j++)
                ans=1ll*(ans+1ll*dp[i][j]*dp[k-i][j]%Mod)%Mod;
        for (int i=1;i<k-1;i++)
            for (int j=i;j<=n*k;j++)
                ans=1ll*(ans+1ll*dp[i][j]*dp[k-1-i][j]%Mod)%Mod;
        printf("%d\n",ans);
    }
    return 0;
}

 

HEOI2014 平衡

原文:https://www.cnblogs.com/ckr1225/p/9451974.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!