zoukankan      html  css  js  c++  java
  • 某dp题

    【NOI联考by ysy】庆典

    2016年6月17日1,1040

    【题目描述】

    战狂在昌和帝国的首都法法城召开了庆典,向一万名最杰出的士兵分发了用魔法猪做的猪肉饺子,士兵们吃了猪肉饺子后,战斗力大幅提高。
    为了保护战狂的安全以及维护现场秩序,大预言家抽调了n名普通士兵组成了m个小队完成一些不同的任务。由于一些特殊的原因,所有小队的人数都互不相同。
    你需要求出有多少种可能的组队方案。注意士兵是相同的,而小队是不同的。

    【输入数据】

    第一行两个个整数n,m。

    【输出数据】

    一行一个数表示答案。对998244353取模。

    【样例输入】

    16 4

    【样例输出】

    216

    【数据范围】

    对于20%的数据,n,m<=20。
    对于50%的数据,n,m<=3000。
    对于100%的数据,n,m<=100000。

    这个题目就比较简单
    首先所有小队的人都不相同
    那就先给每个位置(i)分配(i)个队员
    对于剩下的人就分配给这m个小队
    所以就(O(nm))递推

    这个递推有点熟悉(整数拆分问题)

    递推法
    根据n和m的关系,考虑下面几种情况:
    (1)当n=1时,不论m的值为多少(m>0),只有一种划分,即({1})
    (2)当m=1时,不论 的值为多少(n>0),只有一种划分,即({1,1,....1,1,1})
    (3)当n=m时,根据划分中是否包含n,可以分为两种情况:
    (a)划分中包含n的情况,只有一个,即({n})
    (b)划分中不包含n的情况,这时划分中最大的数字也一定比n小,即n的所有((n-1))划分;
    因此,(f(n,n)=1+f(n, n-1))
    (4)当n时,由于划分中不可能出现负数,因此就相当于f(n,n);
    (5)当n>m时,根据划分中是否包含m,可以分为两种情况:
    (a)划分中包含 的情况,即{m,{x1,x2,x3,...,xi}},其中{x1,x2,x3,...,xi}的和为n-m,可能再次出现m,因此是(n-m)的m划分,因此这种划分个数为f(n-m,m;
    (b)划分中不包含m的情况,则划分中所有值都比m小,即n的(m-1)划分,个数为f(n,m-1;
    因此,f(n,m)=f(n-m,m)+f(n,m-1) 。
    综合以上各种情况,可以看出,上面的结论具有递归定义的特征,其中(1)和(2)属于回归条件,(3)和(4)属于特殊情况,而情况(5)为通用情况,属于递归的方法,其本质主要是通过减少n或m以达到回归条件,从而解决问题。
    详细递推公式描述如下:

    那么

    #include<iostream>
    #include<cstdio>
    #define N 100005
    #define mod 998244353
    using namespace std;
    
    int dp[N];
    
    int main(){
    	int n,m;
    	cin>>n>>m;
    	n-=m*(m+1)/2;
    	dp[0]=1;
    	for(int i=1;i<=m;++i)
    		for(int j=i;j<=n;++j)
    			dp[j]=(dp[j]+dp[j-i])%mod;
    	for(int i=2;i<=m;++i)
    		dp[n]=(dp[n]*i)%mod;
    	printf("%d",dp[n]);
    	return 0;
    }
    
  • 相关阅读:
    WPF ViewModel 调用任意前台控件的方法
    xxxx
    modelsim一些error(warning)的原因
    [verilog] inout端口处理
    [c语言]指针数组和数组指针
    电机控制术语
    MAC和PHY关系
    IAR map文件说明
    [corterm3]汇编语法
    TI 2802x系列中断系统及应用
  • 原文地址:https://www.cnblogs.com/qdscwyy/p/7806133.html
Copyright © 2011-2022 走看看