1. 程式人生 > >滴滴出行 數字和為sum的方法數(dp)

滴滴出行 數字和為sum的方法數(dp)

給定一個有n個正整數的陣列A和一個整數sum,求選擇陣列A中部分數字和為sum的方案數。 當兩種選取方案有一個數字的下標不一樣,我們就認為是不同的組成方案。

輸入描述:

輸入為兩行:
 第一行為兩個正整數n(1 ≤ n ≤ 1000),sum(1 ≤ sum ≤ 1000)
 第二行為n個正整數A[i](32位整數),以空格隔開。

輸出描述:

輸出所求的方案數

示例1

輸入

複製

5 15 5 5 10 2 3

輸出

複製

4

這道題是給定一個數sum,求陣列中是否存在幾個數相加的和為sum的變形。

給定陣列dp[i][j]表示組成j的情況在第i個值時有幾種情況;要想符合情況就是有if(j > a[i])dp[i-1][j - a[i]] + dp[i][j-1];else dp[i-1][j];

程式碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
using namespace std;
typedef long long ll;
const int maxn = 1000 + 10;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-10;
const ll mod = 1e9 + 7;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline int read(){
    int ret=0,f=0;char ch=getchar();
    while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
    while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
    return f?-ret:ret;
}
int n,sum;
ll a[maxn];
ll dp[maxn][maxn];
int main(){
	scanf("%d%d",&n,&sum);
	for(int i= 1; i<=n; i++){
		scanf("%lld",&a[i]);
	}

	memset(dp, 0, sizeof(dp));
	dp[0][0] = 1;//賦初始值。表示第0個數組值構成0的情況是一種。
	for(int i = 1; i <= n; i++){
		for(int j = 0; j <= sum; j++){
			if(j >= a[i]){
				dp[i][j] = dp[i-1][j] + dp[i-1][j-a[i]];
			}else{
				dp[i][j] = dp[i-1][j];
			}
		}
	}
	printf("%lld\n",dp[n][sum]);
	return 0;
}

題目大意就是給定一個數組其中陣列的值的個數不限問可以組成sum的種類有多少。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
using namespace std;
typedef long long ll;
const int maxn = 100 + 10;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-10;
const ll mod = 1e9 + 7;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline int read(){
    int ret=0,f=0;char ch=getchar();
    while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
    while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
    return f?-ret:ret;
}
int n, m; 
int a[maxn];
int dp[maxn];
int main(){
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= n; i ++){
		scanf("%d",&a[i]);
	}
	memset(dp, 0, sizeof(dp));
	dp[0] = 1;
	for(int i = 1; i <= m; i++){
		for(int j = 0; j <= n; j++){
			if(i >= a[j]){
				dp[i] += dp[i-a[j]];
			}
		}
	}
	
	printf("%d ",dp[m]);

	return 0;
}