動態規劃-思考解決動態規劃問題

關於動態規劃,過了一段時間,自己給自己做一個小結.
給你一道題目:

題目題意:
一個n*n的方格.
從(1,1)進去,從(n,n)出;
每一個交叉點都有花生,每次只能是向下或者向右走。
讓你找出走過路線中能踩到的花生的數量最多是多少?

給出的數據分析:
驗證正確

思考:

傳統思考方式
要思考這個幾個東西,但自己總覺得沒那麼高的水平.(cai)
可行性 階段,決策,最優子結構,無後效性。

所以我決定找一種更合適我的方式去思考動態規劃這類問題:
每個人都有自己喜歡的和習慣,這纔是我自己

從集合角度來考慮DP問題
對於合適自己的思考,我通常是將DP問題,化爲一個集合的角度去思考,比如下面圖片:
這個是自己在做一個問題的思考.

**加粗樣式**

摘花生 表示的屬性是max
從(1,1)走到(i,j)的最大值
從(1, 1 ) 走到 (i , j)的所有路線的最大值
f(n,n)就是最大值

動態規劃

1.狀態表示
f[i][j] 集合 所有從(1,1)走到(i,j)的路線代表的值
屬性 : max /min/數量

2.狀態的計算
f[i,j] 整個集合,分而治之
最後一步是從是上面 過來的
最後一步是 從左邊過來的 max(左,上) max(f[i-1][j]+w[i][j] f[i][j-1]+w[i][j])

狀態的計算 ——集合的劃分

劃分原則:

1.不重複(有的時候並不需要,而有點時候是需要的)
2.不漏

很重要的劃分依據:“最後”:

#include <bits/stdc++.h>
#define pb(a) push_back(a)
#define pf push_front
#define beg begin
#define rb rbegin0
#define re rend
#define nd cout<<endl
#define all(s) s.begin(),s.end()
#define pi acos(-1.0)
#define MaxN  0x3f3f3f3f
#define MinN  0xc0c0c0c0
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int N=1e3+15;
int n,m;
int dp[N][N];
int w[N][N];
int main()
{
    while(cin>>n>>m)
    {
        memset(dp,0,sizeof(dp));
        for( int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                cin>>w[i][j];
            }
        }
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                dp[i][j]=max(dp[i-1][j],dp[i][j-1])+w[i][j];//這個的單獨
            }
        }
        cout<<dp[n][m]<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章