二數之和

給定一個數組和一個數k
如果在這個數組能任意找到二個數組相加得到給定的k 便返回true 否則返回false

樣例輸入
6
2 34 12 4 5 8
9

輸出
true

分析:
同樣先自頂向下分析
拿上面的例子 從最後的數字8開始向前推 對於每個數字有取或不取二種方案,
如果取
subset(arr,i-1,s-arr[i]) 表示那要求得的值減去取的當前值,接着在從前面 i-1 個數中找能湊成
s-arr[i]
如果不取
那就是從前面 i-1個數中湊 s

接着找到遞歸出口

  1. 如果s等於0返回true
  2. 如果只剩最後一個數,但這個數不等於你需要的數 返回false 反之返回true
  3. 如果要減去的數比自身還要大 直接不取這個數
#include<iostream>
#include<algorithm>
using namespace std;
int arr[101];
int n;
bool rec_subset(int i, int total) {
 if (total == 0)
  return true;
 else if (i == 0)
  return arr[i] == total;
 else if (arr[i] > total)
  return rec_subset(i - 1, total);
 else
  return rec_subset(i - 1, total - arr[i]) || rec_subset(i - 1, total);
}
int main()
{
 cin >> n;
 for (int i = 0;i < n;i++)
  cin >> arr[i];
 int total;
 cin >> total;
 cout << rec_subset(n - 1, total);
}

動態規劃

二維數組的行就代表arr的每一行下標 列就代表0-total
遞推 所以先初始化第0行和第0列
根據上面的遞歸出口:
第1行到第n-1行的第0列都爲true 因爲數組還沒有用完total就已經爲0了
第0行的每一列都爲false除了下標爲arr[0]的 因爲第0行表示就剩這一個數字了 只有和我需要的數字相等才爲true

#include<iostream>
using namespace std;
int dp[100][100];
int n;
int total;
int arr[100];
int main()
{
 cin >> n;
 for (int i = 0;i < n;i++)
  cin >> arr[i];
 cin >> total;
 for (int i = 0;i < n;i++)
  dp[i][0] = 1;
 dp[0][arr[0]] = 1;
 for (int i = 1;i <n;i++) {
  for (int j = 1;j <= total;j++) {
   if (arr[i] > j)
    dp[i][j] = dp[i - 1][j];//如果比需要的大直接不取這個數字 在上面的i-1個裏面取
   else {
    //取自己或者不取自己 有一個滿足即可
    int a = dp[i][j - arr[i]];
    int b = dp[i-1][j];
    dp[i][j] = a || b;
   }
  }
 }
 cout << dp[n - 1][total-1]<<endl;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章