动态规划——棋盘
數(shù)字三角形 經(jīng)典例題,有記憶化搜索,正推,逆推三種方法 如果記錄路徑,可以開一個數(shù)組記錄狀態(tài)是由哪個子狀態(tài)推出來的 #include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>using namespace std;
const int maxn = 200;
int n,dp[maxn][maxn],value[maxn][maxn];int main(){cin>>n;for(int i = 1;i <=n;i++){for(int j = 1;j <= i;j++){cin>>value[i][j];}}memset(dp,-1,sizeof(dp));for(int i = 1;i <= n;i++) dp[n][i] = value[n][i];for(int i = n - 1;i >= 1;i--){for(int j = 1;j <= i;j++){dp[i][j] = value[i][j] + max(dp[i+1][j],dp[i+1][j+1]);}} cout<<dp[1][1];return 0;
}
數(shù)字三角形w
同數(shù)字三角形,要求數(shù)字總和取模100后最大,既然總和大的余數(shù)不一定大,所以轉(zhuǎn)化為可行性判斷
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int n,dp[50][50][105],map[50][50],ans = 0; int x,y; int main(){cin>>n;for(int i = 1;i <= n;i++){for(int j = 1;j <= i;j++){scanf("%d",&map[i][j]);}}dp[1][1][map[1][1]%100] = 1;for(int i = 2;i <= n;i++){for(int j = 1;j <= i;j++){for(int k = 0;k <= 99;k++){if(dp[i-1][j-1][k] || dp[i-1][j][k]){dp[i][j][(k+map[i][j])%100] = 1;if(i == n) ans = max(ans,(k+map[i][j])%100); }}}}cout<<ans;return 0; }數(shù)字三角形ww
同數(shù)字三角形,要求必須經(jīng)過x div 2,y div 2這個點
有一個技巧,把這個點的值加上一個特別大的數(shù),就一定會經(jīng)過這個點
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int n,dp[50][50],map[50][50],ans = 0,hehe = 100000000; int main(){cin>>n;for(int i = 1;i <= n;i++){for(int j = 1;j <= i;j++){scanf("%d",&map[i][j]);}}map[n/2][n/2] += hehe;for(int i = 1;i <= n;i++){for(int j = 1;j <= i;j++){dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]) + map[i][j];ans = max(dp[i][j],ans);}}cout<<ans-hehe;return 0; }數(shù)字三角形www
同上個題,只不過必過點任意
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int n,dp[50][50],map[50][50],ans = 0,hehe = 100000000; int x,y; int main(){cin>>n;for(int i = 1;i <= n;i++){for(int j = 1;j <= i;j++){scanf("%d",&map[i][j]);}}cin>>x>>y;map[x][y] += hehe;for(int i = 1;i <= n;i++){for(int j = 1;j <= i;j++){dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]) + map[i][j];ans = max(dp[i][j],ans);}}cout<<ans-hehe;return 0; }最低通行費(fèi)用
從左上角到右下角,往右或往下走,使沿途的權(quán)值和最小
一定要注意邊界的問題
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> using namespace std; int main(){int map[105][105],dp[105][105],n;cin>>n;for(int i = 1;i <= n;i++){for(int j = 1;j <= n;j++){cin>>map[i][j];}}for(int i = 1;i <= n;i++){for(int j = 1;j <= n;j++){if(i > 1 && j > 1)dp[i][j] = map[i][j] + min(dp[i-1][j],dp[i][j-1]);else if(i > 1 && j == 1) dp[i][j] = map[i][j] + dp[i-1][j];else if(j > 1 && i == 1) dp[i][j] = map[i][j] + dp[i][j-1];else dp[i][j] = map[i][j];}}cout<<dp[n][n];return 0; }?
?Wikioi 2152 滑雪
題目描述?Descriptiontrs喜歡滑雪。他來到了一個滑雪場,這個滑雪場是一個矩形,為了簡便,我們用r行c列的矩陣來表示每塊地形。為了得到更快的速度,滑行的路線必須向下傾斜。
例如樣例中的那個矩形,可以從某個點滑向上下左右四個相鄰的點之一。例如24-17-16-1,其實25-24-23…3-2-1更長,事實上這是最長的一條。
輸入文件
第1行: 兩個數(shù)字r,c(1<=r,c<=100),表示矩陣的行列。
第2..r+1行:每行c個數(shù),表示這個矩陣。
輸出文件
僅一行: 輸出1個整數(shù),表示可以滑行的最大長度。
樣例輸入?Sample Input5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
25
數(shù)據(jù)范圍及提示?Data Size & Hint1s
思路: 枚舉起點+記憶化搜索 代碼: 1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<algorithm> 6 #define mx 150 7 #define maxint 10000000 8 using namespace std; 9 int r,c,a[mx][mx],vis[mx][mx],bx,by,mn,dp[mx][mx],ans; 10 void input(){ 11 cin>>r>>c; 12 mn = 0; 13 memset(a,maxint,sizeof(a)); 14 for(int i = 1;i <= r;i++){ 15 for(int j = 1;j <= c;j++){ 16 cin>>a[i][j]; 17 if(a[i][j] > mn){ 18 mn = a[i][j]; 19 by = i; 20 bx = j; 21 } 22 } 23 } 24 25 } 26 int dfs(int y,int x){ 27 if(vis[y][x]) return dp[y][x]; 28 vis[y][x] = 1; 29 if(y - 1 > 0 && a[y][x] > a[y-1][x])dp[y][x] = max(dp[y][x],dfs(y-1,x)); 30 if(y + 1 <= r && a[y][x] > a[y+1][x])dp[y][x] = max(dp[y][x],dfs(y+1,x)); 31 if(x - 1 > 0 && a[y][x] > a[y][x-1])dp[y][x] = max(dp[y][x],dfs(y,x-1)); 32 if(x + 1 <= c && a[y][x] > a[y][x+1])dp[y][x] = max(dp[y][x],dfs(y,x+1)); 33 return ++dp[y][x]; 34 } 35 void work(){ 36 ans = 0; 37 38 for(int i = 1;i <= r;i++){ 39 for(int j = 1;j <= c;j++){ 40 dfs(i,j); 41 } 42 } 43 for(int i = 1;i <= r;i++){ 44 for(int j = 1;j <= c;j++){ 45 ans = max(ans,dp[i][j]); 46 } 47 } 48 cout<<ans<<endl; 49 } 50 int main(){ 51 input(); 52 work(); 53 return 0; 54 } View Code?
?難題:
傳紙條(多線程dp,最優(yōu)性方法解決判定問題)No.3
?
轉(zhuǎn)載于:https://www.cnblogs.com/hyfer/p/4841868.html
總結(jié)
- 上一篇: initWithFrame方法的理解(转
- 下一篇: Cannot SET AUTOTRACE