平衡方案(統計使天平平衡的方案數——每個砝碼數量無限)

平衡方案

Description

天平的一側物體重量爲M,該天平有N種砝碼,每種砝碼都有很多,求保持天平平衡,砝碼搭配的方案數。

Input

第二行兩個整數N,M

第二行N個整數,表示各種砝碼的重量

Output

一個整數 ANS 表示所有非負整數對(X1,X2,。。。Xn)的個數,如果答案超過了9位數,你只需輸出ANS mod 10^9的值即可。

Sample Input Copy

5 5
1 2 3 4 5

Sample Output Copy

7

HINT

數據規模

1<=N<=1000,0<=M<=1000

分析
不同於之前的平衡方案,這裏是有一個關鍵詞的——“有n種砝碼”,也就是說,數量是無限的
當然,是在可取的範圍內無限的(不超出要稱重的物品的質量
同樣,我們從 f[n][m] 放到第n種砝碼時的方案數來分析
但是一個砝碼能用多次
所以這裏,我們可以將一個物品的取的數量限定爲 k
k 的範圍便是 0 ≤ k ≤ m/a[n] (a[n]表示第n個砝碼的質量)
因爲 k 的取值可以是零,也就是不放,所以我們這裏可以取消對不放的特判
而是主要來判斷放的情況
同樣,如果放一個或是多個的話,都是用 k 來代表的
所以我們可以得到狀態轉移方程:
f[n][m] += f[n-1][m-a[i]*k] (a[n]表示第n個砝碼的質量)
同樣,後面便是到初始化了
相同於前面的,這裏也給出圖來:
在這裏插入圖片描述
圖中黃色的部分也就是我們初始化爲1的地方
在稱質量爲0的物品時,我們只有一種方法,什麼都不放
之後是第一行
在不超過需要稱重的物品的質量的範圍內我們可以用 k * a[1] 稱出的質量同樣初始化爲1

代碼

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <math.h>
#include <stdio.h>
#include <queue>
#include <stack>
#include <vector>
using namespace std;

long long mod = 1000000000;
int f[1009][1009],a[1009];
int n,m;

int main() {
	scanf("%d %d",&n,&m);
	for (int i = 1; i <= n; i++) scanf("%d",&a[i]);
	
	for (int i = 1; i <= n; i++) f[i][0] = 1;
	for (int j = 1; j <= m; j++)  if (j % a[1] == 0) f[1][j] = 1;
	//for (int j = 1; j <= m; j++) f[1][j] = j/a[1];  也可以這樣寫 

	for (int i = 2; i <= n; i++)
		for (int j = 1; j <= m; j++)
			for (int k = 0; k <= j/a[i]; k++)
				f[i][j] += f[i-1][j-a[i]*k],
				f[i][j] %= mod;
	
	printf("%d",f[n][m]);
	
	return 0; 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章