動態規劃之記憶化搜尋
阿新 • • 發佈:2021-02-19
技術標籤:動態規劃
有的時候有些資料會被重複計算多次,為了避免被重複使用,專門開一個dp陣列來記錄已經算過的值,一般用memset賦值為-1,若後面遇到這個陣列值為-1說明還沒有算過,就繼續後面的運算
1.https://vjudge.net/contest/419435#problem/A(記憶化搜尋減少重複計算)
#include<iostream>
#include<cstring>
#define maxn 361
using namespace std;
int n,dp[maxn][maxn];
int maxsum[maxn][maxn];//專門開的記錄已經算出答案的陣列
int dfs(int y,int x){
if(maxsum[y][x] != -1) return maxsum[y][x];//如果不等於-1說明已經算過了,直接返回這個值即可
if(y == n) maxsum[y][x] = dp[y][x];//帶回記錄這個數值的陣列
else maxsum[y][x] = max(dfs(y + 1,x),dfs(y + 1,x + 1)) + dp[y][x];
//這個數值取和不取兩種情況取最大,帶回這個陣列的值
return maxsum[y][x];
}
int main(){
ios::sync_with_stdio (false);
cin.tie(0);cout.tie(0);
memset(maxsum,-1,sizeof(maxsum));//給專門記錄的陣列賦值為-1
cin >> n;
for(int i = 1;i <= n;i++)
for(int j = 1;j <= i;j++)
cin >> dp[i][j];
cout << dfs(1,1);
return 0;
}
2.https://vjudge.net/contest/419435#problem/B
#include<iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e6 + 10;
const int INF = 1e9;
int n,dp[maxn];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n;
dp[1] = 1,dp[2] = 2;
for(int i = 3;i <= n;i++){
if(i % 2 == 1) dp[i] = dp[i - 1] % INF;
else dp[i] = (dp[i - 2] + dp[i / 2]) % INF;
}
cout << dp[n];
return 0;
}