動態規劃:數字組合
阿新 • • 發佈:2019-01-31
描述
有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的不同的組合方式的數目。 樣例輸入
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; }