zoukankan      html  css  js  c++  java
  • 题解 [51nod1201] 整数划分

    题面

    解析

    首先,因为是不同的数字,

    可以从小到大依次枚举加上每一个数字的贡献,再枚举每个数.

    然而这样会T掉...

    考虑到(n)只有(50000),

    当分成的数最多时,设最大的数为(m),

    (1+2+3...+m<=n),

    所以最多只会分成315个数((m<316)).

    那么设(f[j][i])表示把(j)分成(i)个数的方案数.

    依次枚举加上的数(i),

    那么这个(i)要么作为单独的一块加上去,

    要么就分成(i)块给之前的贡献过的每个数加1.

    所以转移方程:(f[j][i]-f[j-i][i-1]+f[j-i][i]).

    最后(ans=sum_{i=1}^{315}f[n][i]).

    code(可能代码里面有一些时候大于了315别在意):

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define filein(a) freopen(a".cpp","r",stdin)
    #define fileout(a) freopen(a".cpp","w",stdout);
    using namespace std;
    
    inline int read(){
    	int sum=0,f=1;char c=getchar();
    	while((c<'0'||c>'9')&&c!=EOF){if(c=='-') f=-1;c=getchar();}
    	while(c>='0'&&c<='9'&&c!=EOF){sum=sum*10+c-'0';c=getchar();}
    	return sum*f;
    }
    
    const int N=50001;
    const int Mod=1000000007;
    int n,f[N][401];
    
    int main(){
    	n=read();f[1][1]=1;
    	for(int i=1;i<=320;i++){
    		for(int j=i+1;j<=n;j++) f[j][i]=(f[j-i][i]+f[j-i][i-1])%Mod;
    	}
    	int ans=0;
    	for(int i=1;i<=320;i++) ans=(ans+f[n][i])%Mod;
    	printf("%d
    ",ans);
    	return 0; 
    }
    
    
  • 相关阅读:
    FlowNet2.0论文笔记
    LeetCode NO477.汉明距离总和
    自然语言的分词方法之N-gram语言模型
    C++函数模板及其实例化和具体化
    Vue2源码解读(5)
    Vue2源码解读(4)
    Vue2源码解读(3)
    Vue2源码解读(2)
    Vue2源码解读(1)
    vue的双向绑定原理及实现
  • 原文地址:https://www.cnblogs.com/zsq259/p/11409030.html
Copyright © 2011-2022 走看看