zoukankan      html  css  js  c++  java
  • 6.12 考试 + 总结

    T1 celebration

    • 题目大意 把n分成每个大小不同的正整数的方案数,有序

    • 我们可以先求出无序的数量,再乘一下阶乘就可以了

      • 考试时比较无脑,多开了一位状态,f[i][j][0]表示把i分成j个不同的数并且最小的树不为1的方案数,f[i][j][1]代表最小的数为1的方案数

        • 这样dp状态,f[i][j][0] = f[i-j][j][0]+f[i-j][j][1], f[i][j][1] = f[i-1][j-1][0];
      • 其实可以去掉最后一维,f[i][j] = f[i-j]j+f[i-1-(j-1)]j-1;

      • 题解还给了另外一种做法,我们首先给每块分配给i的大小,然后把剩下的数分成若干个1~m的数,每一个被划分出来的数相当于给(n-i+1,n)的数同时加1,这样保证了递增,而且可以覆盖所有的情况

    
    #define MAXN 100010UL
    #include <cstdio>
    #define Mod 998244353
    
    using namespace std;
    
    int n, m, f[2][MAXN][2];
    
    int main() {
    	freopen("celebration.in", "r", stdin);
    	freopen("celebration.out", "w", stdout);
    	scanf("%d%d", &n, &m);
    	if(1ll*m*(m+1)>2*n) {
    		printf("0");
    		return 0;
    	}
    	int lt = 1, nw = 0;
    	f[0][0][0] = 1;
    	for(int i = 1 ; i <= m ; ++ i) {
    		lt ^= 1, nw ^= 1;
    		int l = (i*(i+1))/2;
    		for(int j = 0 ; j < l && j <= n ; ++ j) f[nw][j][0] = f[nw][j][1] = 0;
    		for(int j = l ; j <= n ; ++ j) {
    			f[nw][j][0] = f[nw][j-i][0]+f[nw][j-i][1];
    			if(f[nw][j][0]>=Mod) f[nw][j][0] -= Mod;
    			f[nw][j][1] = f[lt][j-1][0];
    		}
    	}
    	int ans = f[nw][n][0]+f[nw][n][1];
    	if(ans>=Mod) ans -= Mod;
    	for(int i = 1 ; i <= m ; ++ i) ans = 1ll*ans*i%Mod;
    	printf("%d", ans);
    	return 0;
    }    
    
  • 相关阅读:
    Swift中的可选链与内存管理(干货系列)
    Swift中的类型转换
    Swift中类与结构的初始化
    Swift3中函数的使用
    Java常用的公共方法
    Eclipse中添加文档注释快捷键
    SVN服务器的搭建(三)
    SVN服务器的搭建(二)
    SVN服务器的搭建(一)
    多线程常见的例子
  • 原文地址:https://www.cnblogs.com/assassain/p/5578300.html
Copyright © 2011-2022 走看看