数字组合/自然数拆分

CH

题意:在N个数中找出其和为M的若干个数.((1<N<100),M(1<M<10000)),输出组合的个数.

分析:01背包问题的模板,N个正整数就是N个物品,M就是背包的容积.把max函数改为求和即可.

#include<bits/stdc++.h>
using namespace std;
inline int read(){
   int s=0,w=1;char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
   return s*w;
}
int a[105],f[10005];
int main(){
    int n=read(),m=read();
    for(int i=1;i<=n;i++)a[i]=read();
    f[0]=1;
    for(int i=1;i<=n;i++)
		for(int j=m;j>=a[i];j--)
	    	f[j]+=f[j-a[i]];
    printf("%d
",f[m]);
    return 0;
}

CH

题意:给定一个自然数N,要求把N拆分成若干个正整数相加的形式,参与加法运算的数可以重复。求拆分的方案数 mod 2147483648的结果

分析:完全背包模板,N个物品,每个物品可以被使用无限次.

#include<bits/stdc++.h>
using namespace std;
inline int read(){
   int s=0,w=1;char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
   return s*w;
}
const int mod=2147483648;
unsigned int f[4005];
int main(){
    int n=read();
    f[0]=1;
    for(int i=1;i<=n;i++)
		for(int j=i;j<=n;j++)
	    	f[j]=(f[j]+f[j-i])%mod;
    printf("%d
",f[n]>0?f[n]-1:2147483647);
    return 0;
}

原文地址:https://www.cnblogs.com/PPXppx/p/10939989.html