• BZOJ3612 [Heoi2014]平衡 整数划分


    [Heoi2014]平衡

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 348  Solved: 273
    [Submit][Status][Discuss]

    Description

    下课了,露露、花花和萱萱在课桌上用正三棱柱教具和尺子摆起了一个“跷跷板”。
         这个“跷跷板”的结构是这样的:底部是一个侧面平行于地平面的正三棱柱教具,
    上面 摆着一个尺子,尺子上摆着若干个相同的橡皮。尺子有 2n + 1 条等距的刻度线,
    第 n + 1 条 刻度线恰好在尺子的中心,且与正三棱柱的不在课桌上的棱完全重合。
         露露发现这个“跷跷板”是不平衡的(尺子不平行于地平面)。于是,她又在尺
    子上放 了几个橡皮,并移动了一些橡皮的位置,使得尺子的 2n + 1 条刻度线上都恰
    有一块相同质 量的橡皮。“跷跷板”平衡了,露露感到很高兴。
         花花觉得这样太没有意思,于是从尺子上随意拿走了 k 个橡皮。令她惊讶的事
    情发生了: 尺子依然保持着平衡!
         萱萱是一个善于思考的孩子,她当然不对尺子依然保持平衡感到吃惊,因为这
    只是一个 偶然的事件罢了。令她感兴趣的是,花花有多少种拿走 k 个橡皮的方法
    ,使得尺子依然保 持平衡?
    当然,为了简化问题,她不得不做一些牺牲——假设所有橡皮都是拥有相同质量的
     质点。但即使是这样,她也没能计算出这个数目。放学后,她把这个问题交给了她
    的哥哥/ 姐姐——Hibarigasaki 学园学生会会长,也就是你。当然,由于这个问题
    的答案也许会过于 庞大,你只需要告诉她答案 mod p 的值。

    Input

    第一行,一个正整数,表示数据组数 T(萱萱向你询问的次数)。   

      接下来 T 行,每行 3 个正整数 n, k, p。 

    Output

    共 T 行,每行一个正整数,代表你得出的对应问题的答案。 

     

    Sample Input

    10
    6 5 10000
    4 1 10000
    9 6 10000
    4 6 10000
    5 1 10000
    8318 10 9973
    9862 9 9973
    8234 9 9973
    9424 9 9973
    9324 9 9973

    Sample Output

    73
    1
    920
    8
    1
    4421
    2565
    0
    446
    2549

    HINT

     T <= 20,1 <= n <= 10000,1 <= k <= 10,2 <= p <= 10000,且 k <= 2n+1。

    设f(i, j)表示把i分成j个不同的且<= n的整数的方案数。

    考虑一般的整数划分数问题,f(i, j) = f(i-1, j-1) + f(i-j, j),其中第一项表示新填一个1,第二项表示把所有数都加1。

    顺着这个思路,我们先考虑“不同”这个限制。

    显然我们不能直接新填一个1,所以我们考虑把所有数加1,搞出来一个1,第一项得出为f(i-j, j-1)

    第二项同样为f(i-j, j).

    所以状态转移方程为f(i, j) = f(i-j, j) + f(i-j, j-1).

    再考虑不能超过n这个限制,如果有超过n的数,显然它只有一个,而且是n+1,所以我们把这些情况减掉,即f(i-n-1, j-1).

    统计答案时,考虑选了0和不选0,两种情况,并特判k=1.

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #define N 101001
     6 #define M 15
     7 using namespace std;
     8 int n,m,p,w;
     9 int f[N][M]; // f[i][j] 表示
    10 //将i划分成j个互不相同的正整数,
    11 // 且最大不超过n 的划分方案数
    12 int main()
    13 {
    14     int i,j,k,g;
    15     f[0][0]=1;
    16     for(scanf("%d",&g);g--;)
    17     {
    18         scanf("%d%d%d",&n,&m,&p);
    19         if(m==1)
    20         {
    21             puts("1");
    22             continue;
    23         }
    24         w=n*(m-1);
    25         for(i=1;i<=w;i++)
    26             for(j=1;j<m;j++)
    27             {
    28                 f[i][j]=(i>=j?(f[i-j][j]+f[i-j][j-1]):0);
    29                 f[i][j]=(i>=n+1)?(f[i][j]-f[i-n-1][j-1]):f[i][j];
    30                 f[i][j]=(f[i][j]%p+p)%p;
    31             }
    32         long long ans=0;
    33         for(i=1;i<=w;i++)
    34             for(j=1;j<m;j++)
    35                 ans+=f[i][j]*f[i][m-j],ans%=p;
    36         for(i=0;i<=w;i++)
    37             for(j=1;j<m-1;j++)
    38                 ans+=f[i][j]*f[i][m-1-j],ans%=p;
    39         printf("%lld
    ",ans);
    40     }
    41 }
  • 相关阅读:
    win10 开机背景图
    关于在不知道具体实例化哪个窗体时调用该窗体公共变量的方法
    devexpress 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 “lc.exe”已退出,代码为 -1。
    获取打印机设置的纸张参数
    mysql 添加字段语句
    curl模拟post请求
    php CI框架log写入
    winform程序更新
    JSP的EL和JSTL解析
    报错:java.lang.IllegalArgumentException: object is not an instance of declaring class
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8286971.html
Copyright © 2020-2023  润新知