zoukankan      html  css  js  c++  java
  • 整数划分

    【题目描述】
    给定整数 (N),求分解成(2)的幂的方案数。结果(Mod 1000000007),比如 (N = 7) 时,共有 (6) 种划分方法。
    (7=1+1+1+1+1+1+1 \ =1+1+1+1+1+2 \ =1+1+1+2+2 \ =1+2+2+2 \ =1+1+1+4 \ =1+2+4 \)

    【输入格式】
    输入一个数(N)((1 le N le 10^6))

    【输出格式】
    输出划分方法的数量 (Mod 000000007)

    第一眼看好像是结论题 于是推了好久的结论。。。没推出来 然后就去写DP
    结果到最后也只写了个错误的背包

    做法1 完全背包
    物品就是(2^0 2^1 2^2 cdots) 然后跑个板子就行了。。。
    借下学长代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 1000000 
    #define mod 1000000007 
    using namespace std;
    typedef long long ll;
    int n;
    int sz;
    int bin[maxn+5];
    ll dp[maxn+5];
    int main(){
    	scanf("%d",&n);
    	bin[0]=1;
    	while(bin[sz]*2<=n){
    		sz++;
    		bin[sz]=bin[sz-1]*2;
    	} 
    	dp[0]=1;
    	for(int i=0;i<=sz;i++){
    		for(int j=bin[i];j<=n;j++){
    			dp[j]+=dp[j-bin[i]];
    			dp[j]%=mod;
    		}
    	}
    	printf("%lld
    ",dp[n]);
    }
    

    时间复杂度 (O(n log n))

    做法2 递推
    可以分别考虑将当前数字拆分出几个1
    (f[i])代表(i)有多少种拆分方案
    (f[9])为例 如果把9拆分成1个1 和 其他一些数字 则方案数就等于(将8用2, 4, 8拆分的方案数) 其实也就是 (将4用1, 2, 4拆分的方案数) 即(f[4])
    同理 把9拆分成3个1和其他数字时 方案数会是 (f[3])
    所以可以得出结论 (f[n] = sum_{i=1}^{n/2} f[i]) 这个东西用前缀和维护一下就行
    这么简单的结论我没想到 我太蒻了

    代码

    #include <iostream>
    #include <cstdio>
    using namespace std;
    typedef long long ll;
    
    const ll mod = 1000000007;
    ll n, ans;
    ll a[1000005], sum[1000005];
    
    ll read() {
    	ll ret = 0, flag = 1;
    	char ch = getchar();
    	while (ch > '9' || ch < '0') {
    		if (ch == '-') flag = -1;
    		ch = getchar();
    	}
    	while (ch <= '9' && ch >= '0') {
    		ret = (ret << 3) + (ret << 1) + (ch ^ '0');
    		ch = getchar();
    	}
    	return ret * flag;
    }
    
    int main() {
    	n = read();
    	a[1] = 1; sum[1] = 2;
    	a[0] = 1; sum[0] = 1;
    	for (int i = 2; i <= n; i++) {
    		a[i] = sum[i/2]; sum[i] = (sum[i-1] + a[i]) % mod;
    	}
    	printf("%lld
    ", a[n]);
    	return 0;
    } 
    

    时间复杂度(O(N))

  • 相关阅读:
    利用SuperMap Deskpro进行Peking 54到WGS84的转换
    远程序列化xml文件(可用于自动更新程序中版本号的比较,更新文件的读取等)
    [转]C#导出到EXCEL
    [转]常用数学公式
    CLR Via C#系列学习笔记之委托
    黑马程序员C#语言中的三种循环:while 循环、dowhile 循环、for 循环。
    .net2005中GridView或者Datalist等超級流行的分頁
    Array.splice()删除数组中重复的数据
    .net中常需对文件夹以及常用的操作方法
    文件的上传下载示例
  • 原文地址:https://www.cnblogs.com/ak-dream/p/AK_DREAM13.html
Copyright © 2011-2022 走看看