zoukankan      html  css  js  c++  java
  • Sumsets(完全背包)

    Sumsets
    Time Limit: 2000MS   Memory Limit: 200000K
    Total Submissions: 15045   Accepted: 5997

    Description

    Farmer John commanded his cows to search for different sets of numbers that sum to a given number. The cows use only numbers that are an integer power of 2. Here are the possible sets of numbers that sum to 7: 
    1) 1+1+1+1+1+1+1  2) 1+1+1+1+1+2  3) 1+1+1+2+2  4) 1+1+1+4  5) 1+2+2+2  6) 1+2+4 
    Help FJ count all possible representations for a given integer N (1 <= N <= 1,000,000). 

    Input

    A single line with a single integer, N.

    Output

    The number of ways to represent N as the indicated sum. Due to the potential huge size of this number, print only last 9 digits (in base 10 representation).

    Sample Input

    7

    Sample Output

    6
    题解:让用2^k的数相加组成n,刚看见就说是母函数,没打出来,打出来也肯定不对因为数据量太大肯定超时了;
    其实可以用完全背包写;
    思路很好想,把2^k的物品往背包里面放;dp[j]+=dp[j-i]为方案数;
    递推也很好想,如果是奇数,直接dp[i]=dp[i-1]
    如果是偶数,dp[i]可以由dp[i/2]得到;也可以由dp[i-1]得到;
    完全背包:
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define mem(x,y) memset(x,y,sizeof(x))
    #define T_T while(T--)
    #define SI(x) scanf("%d",&x)
    #define SL(x) scanf("%lld",&x)
    typedef long long LL;
    const int MAXN=1000010;
    const int MOD=1e9;
    int bag[MAXN];
    int main(){
    	int N;
    	 while(~scanf("%d",&N)){
    	 	mem(bag,0);
    	 	bag[0]=1;
    	 	for(int i=1;i<=N;i*=2){
    	 		for(int j=i;j<=N;j++){
    	 			bag[j]+=bag[j-i];
    	 			bag[j]%=MOD;
    			 }
    		 }
    		 printf("%d
    ",bag[N]);
    	 }
    	return 0;
    }
    

      母函数超时:

    #include<stdio.h>
    const int MAXN= 1000010;
    int main(){
        int a[MAXN],b[MAXN],N;
        while(~scanf("%d",&N)){
            int i,j,k;
            for(i=0;i<=N;i++){
                a[i]=1;b[i]=0;
            }
            for(i=2;i<=N;i*=2){
                for(j=0;j<=N;j++)
                    for(k=0;k+j<=N;k+=i)
                        b[j+k]+=a[j];
                    for(j=0;j<=N;j++)
                        a[j]=b[j],b[j]=0;
                }
            printf("%d
    ",a[N]);
        }
        return 0;
    }
    

      递推;

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define mem(x,y) memset(x,y,sizeof(x))
    #define T_T while(T--)
    #define SI(x) scanf("%d",&x)
    #define SL(x) scanf("%lld",&x)
    typedef long long LL;
    const int MAXN=1000010;
    const int MOD=1e9;
    int dp[MAXN];
    int main(){
    	int N;
    	dp[0]=1;
    	for(int i=1;i<MAXN;i++){
    		if(i&1)dp[i]=dp[i-1];
    		else dp[i]=(dp[i-1]+dp[i/2])%MOD;
    	}
    	while(~scanf("%d",&N))printf("%d
    ",dp[N]);
    	return 0;
    }
    

      

  • 相关阅读:
    练习
    圆形时钟
    鼠标经过改变颜色
    Java基础知识精华部分(个人总结)
    Java随机数总结
    java 获取随机数字的三种方法
    网站开发人员应该知道的61件事
    人人都该了解的十大算法
    String 字符串
    面向对象 JAVA代码
  • 原文地址:https://www.cnblogs.com/handsomecui/p/5061234.html
Copyright © 2011-2022 走看看