1. 程式人生 > >動態規劃:數字組合

動態規劃:數字組合

描述 有n個正整數,找出其中和為t(t也是正整數)的可能的組合方式。如:
n=5,5個數分別為1,2,3,4,5,t=5;
那麼可能的組合有5=1+4和5=2+3和5=5三種組合方式。 輸入 輸入的第一行是兩個正整數n和t,用空格隔開,其中1<=n<=20,表示正整數的個數,t為要求的和(1<=t<=1000)
接下來的一行是n個正整數,用空格隔開。 輸出 和為t的不同的組合方式的數目。 樣例輸入
5 5
1 2 3 4 5
樣例輸出
3

題目要求從一堆數字裡找出幾個數字加起來等於某個數有幾種選法;

思路如下:

1.dp[i][j]代表前i個數字和等於j的選法種類,a[i]代表第i個數;

2.j小於等於a[i]時,a[i]不能被選擇,所以dp[i][j]=dp[i-1][j];

j大於a[i]時,a[i]可選可不選,所以dp[i][j]=dp[i-1][j]+dp[i-1][j-a[i]];

程式碼如下:

#include<bits/stdc++.h>
using namespace std;
int main()
{
        int i,j,n,t,a[25],dp[25][1005]={0};
        cin>>n>>t;
        for(i=1;i<=n;i++)
        {
                cin>>a[i];
                dp[i][a[i]]+=1;        //這裡注意因為只選擇a[i]的狀況不會被考慮到,所以要提前增一個
        }
        for(i=1;i<=n;i++)
        {
                for(j=1;j<=a[i];j++)
                {
                        dp[i][j]+=dp[i-1][j];
                }
                for(j=a[i]+1;j<=t;j++)
                {
                        dp[i][j]=dp[i-1][j]+dp[i-1][j-a[i]];
                }
        }
        cout<<dp[n][t]<<endl;
}