1. 程式人生 > >【URAL - 1114 】Boxes (dp,組合數學)

【URAL - 1114 】Boxes (dp,組合數學)

題幹:

N boxes are lined up in a sequence (1 ≤ N ≤ 20). You have A red balls and B blue balls (0 ≤ A ≤ 15, 0 ≤ B ≤ 15). The red balls (and the blue ones) are exactly the same. You can place the balls in the boxes. It is allowed to put in a box, balls of the two kinds, or only from one kind. You can also leave some of the boxes empty. It's not necessary to place all the balls in the boxes. Write a program, which finds the number of different ways to place the balls in the boxes in the described way.

Input

Input contains one line with three integers NA and B separated by space.

Output

The result of your program must be an integer written on the only line of output.

Example

input output
2 1 1
9

解題報告:

   這題首先將問題做了一步簡化(沒想到啊,還是太菜)就是將紅球和藍球分開處理了,那麼我們可以先看全是紅球的,再看全是藍球的,最後相乘不就是結果嗎?換句話說,我們只需要打表往盒子裡裝 球 就可以了。最後需要用哪個的結果直接去表中找不就好了嗎?

   dp[i][j]表示前i個盒子裝入j個球的方案數。。。最後兩者相乘,就是答案、、

AC程式碼:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
unsigned ll dp[22][20];
int n,m;
int main() 
{
	dp[0][0]=1;
	for(int i = 0; i<=15; i++) dp[1][i] = 1;
	for(int i = 2; i<=22; i++) {
		for(int j = 0; j<=15; j++) {
			for(int k = 0; k<=j; k++) {
				dp[i][j] += dp[i-1][k];
			}
		}
	}
	int n,a,b;
	cin>>n>>a>>b;
	unsigned ll ans1 = 0,ans2 = 0;
	for(int i = 0; i<=a; i++) ans1 += dp[n][i];
	for(int i = 0; i<=b; i++) ans2 += dp[n][i];	
	printf("%llu\n",ans1*ans2);//printf("%I64u\n",ans1*ans2);
	return 0 ;
}

總結:

  其實不應該想不到這第一步化簡的。。因為你想啊不然這題不就沒法做了嗎,,,盒子不同,球的顏色不同,但是同色的不同球又相同、、這麼多關係上哪找dp去?所以化簡了之後就是,不同盒子放入相同球的放球問題了。、、

   這題dp的狀態設計還可以這樣(wjh想):dp[i][j]表示截止第i個盒子,第i個盒子中放入j個相同球的方法數。。本來我覺得這肯定不對啊因為你肯定得記錄一下一共放了多少球了啊。他說不用,因為先讀入了a和b的值,所以相當於把後面的球數空出來就可以了,也就是內層迴圈for(int k = 0; k<=j-a; k++)我覺得也可以啊、、 但是仔細一想這樣是行不通的,,會多算了一些方案數,因為你這個狀態是沒啥問題,,但是你用的值得dp[i-1][]的吧,這個就只表示了第i-1個盒子裝的,而前面第i-2個...之類的就沒有考慮到。也就是有很多不能算進去的狀態都算進去了。所以會多算。。