2016 7 28 dp 動態規劃入門練習題

2021-07-15 18:05:38 字數 2659 閱讀 5115

卡題卡得好難受orz。發現自己還是連最基本的dp都沒有掌握,淚目qaq 花了一天時間閱遍資料,還是多少有點啟發的。剩下的就得靠diffuse mode了。

下面開始愉快的刷題模式。一共四十多道,慢慢填坑。

robber:

這道題一看就是0/1揹包啦,因為每種只有拿或不拿兩種選擇。

但是和其他的又有所不同。首先一看這道題,第一反應就是用總概率p當容量。剛開始智障了,以為p相加得到不被抓的概率,後來想想應該是相乘啊喂!這還不算,如果用p當容量,p小數點後面有好多位,就算乘個比較大的數把它化整,也是行不通的。因為概率是相乘的。

所以得用物品總價值當揹包容量。dp陣列裡的值是不被抓的概率。正確的狀態轉移方程應該為:dp[j]=max(dp[j],dp[j-q[i].money]*q[i].v)

初始化dp[0] = 1.

還被坑到了乙個地方。。dp陣列要開到10000,因為100*100.剛開始開到100提示超時,不知道為什麼。

**如下:

#include #include #include #include using namespace std;

typedef structnode;

node r[10003];

int t;

double p;

int n;

int mj;

double dp[10003];

int main()

dp[0] = 1;//不被抓概率

for(int i = 1;i<=n;i++)

for(int j = sum;j>=r[i].money;j--)

dp[j] = max(dp[j-r[i].money]*(1-r[i].p),dp[j]);

for(int i = sum;i>=0;i--)

} memset(dp,0,sizeof(dp));

} return 0;

}

最大報銷額

這道題需要注意:

1.輸入格式問題。scanf中%*+資料型別,意為輸入的時候跳過此資料型別。還有規定格式輸入。

2.因為都是兩位double,所以要×100轉換為int,才可轉換為揹包問題。

區域性變數一定要初始化初始化初始化!!!debug了半天orz

做到這題的時候又意識到自己對dp之認識不足,又去翻翻翻資料。開始用了很奇怪的看上去是dp實則為貪心的演算法,用票數當揹包容量什麼鬼啊摔!

**如下:

#include #include #include #include using namespace std;

typedef structnode;

node shu[33];

int dp[3000003];

int main()

return 0;

}

最大連續子串行

哈哈哈看了這幾天dp還是有用的嘛!竟然1a簡直不能再開心啊哈哈哈哈

這道題關鍵的狀態轉移方程。dp[i]表示以num[i]為最後一項的連續子串行的最大值。這樣就好啦!

分兩種情況,一種是dp[i-1]<=0的。小於0說明越加越小,肯定不行。試了試這個地方加不加等號都可以a,題目中說的i,j必須最小,感覺不是很清楚。如果按題目所說,那麼應該不加等號是正確的。

另一種,大於0的時候直接加加加就行。

同時每一步對應dp[i]記下此時子串行的長度。輸出的時候逆推就好啦

**如下

#include #include #include #include #include using namespace std;

int n;

int num[10004];

int dp[10004];

int len[10004];

int main()

int ma = -99999999;

if(!flag)

else

else

ma = max(dp[i],ma);

}} // printf("2333\n");

int end = 99;

for(int i = 1;i<=n;i++)

} // cout<>n; }

return 0;

}

max sum

簡直智障。。陣列開小了,提示超時。調了半天orz

其實和上面一道題一毛一樣

**如下

#include #include #include #include #include using namespace std;

int n;

int num[100004];

int dp[100004];

int len[100004];

int main()

else

ma = max(dp[i],ma);

} int end = 99;

for(int i = 1;i<=n;i++)

} // while(num[end]==0&&len[end]!=0)

// end--;

mar++;

cout<<"case "<

動態規劃入門(dp)

dp的基本思想,是把大問題轉化成乙個個小問題,然後遞迴解決。所以本質思想的話還是遞迴。dp最重要的是要找到狀態轉移方程,也就是把大問題化解的過程。舉個例子 乙個數字金字塔 112 2332 2243 133 在上面的數字三角形中尋找一條從頂部到底邊的路徑,使得路徑上所經過的數字之和最大。路徑上的每一...

動態規劃入門 DP基礎

1,include using namespace std int main int solve int i,int j int main float p,pj,q,qj int n,mj float dp 5000 int main dp 0 1 for int i 1 i n i for int...

動態規劃入門

1 用 dp 做的題大多數返回值是int boolean,求max min,不能打亂原來輸入順序。2 動態規劃有兩個重要定義,乙個叫 optimal substructure 另乙個叫 overlap subproblem 各種排序 tree 類問題中,都會用到 divide conquer 的思想...