第一行——咕咕咕。
第二行——不吃早飯的後果是會餓,連續不吃早飯的後果是養成了到點兒就餓的生物鐘。別問,問就是在想中午吃點啥。啊啊啊懷念七月上旬醒來就有飯吃的日子qwq
第三行——昨天請了十分鐘的假,sj師哥很爽快(此處存疑)地答應了,然後下一句是
咱也不知道怎麼回事咱也不敢反駁.jpg
於是——
但是我真的不會dp啊qwq以前遇到這樣的題基本都是略過的呢(委屈巴巴.jpg),於是您可以看到一個瘋狂想遞推公式就是想不出來,一上午做不了一個dp的人欲哭無淚。
但剛好趁這個機會練習dp了,嗯嗯迎難而上(滑稽.jpg)。
sj師哥是個好隊長(瘋狂點頭.jpg)
1.SDNU1044
這道題的坑點是“花在花瓶中的先後順序必須與給定順序相同”,也就是說,當第j個瓶放了第i朵fafa後,第i+1朵fafa就只能放在第j+1及其之後的瓶了。
遞推公式:
for(int i = 1; i <= n; ++i)//花
for(int j = 1; j <= m; ++j)//瓶
{
if(i > j)
continue;
else
dp[i][j] = max(dp[i-1][j-1]+a[i][j],dp[i][j-1]);
}
2.HDU1087
思路:用dp[i]存最後一步到dp[i]時候的最大值,外層是初始化爲一步的值,內層是判斷前面有沒有可以跳的點(滿足當前點大於上一個可跳的點),更新dp的值。
沒發現有啥坑。
記得最後再跑一次循環找max。
遞推公式:
for(int i = 0; i < n; ++i)
{
dp[i] = a[i];
for(int j = 0; j < i; ++j)
{
if(a[i] > a[j])
dp[i] = max(dp[i],dp[j]+a[i]);
}
}
SDNU1330這個跟2一樣。
3.HDU1114
思路:用dp存放滿i容量時最少的錢數,枚舉錢的cost和value找最小
遞推公式:
for(int i = 1; i <= volume; ++i)
{
for(int j = 0; j < n; ++j)
{
if(i-c[j] >= 0)
{
dp[i] = min(dp[i],dp[i-c[j]]+v[j]);
}
}
}
4.SDNU1038
思路:只能向右向下,所以當前點可由上一行的同列或同一行的前一列遞推過來。
遞推公式:
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= n; ++j)
{
dp[i][j] = max(dp[i-1][j],dp[i][j-1])+tu[i][j];
}
}
思路:1.用dp[i][j]表示到有i個Aj個B的時候的方案數
2.dp[i][j]可以由dp[i-1][j]和dp[i][j-1]得到
3.利用貪心的策略,前n個A一定爲AB的A,前m個B一定爲BA的B,便於其組成AB和BA
4.i個A的時候,只要是前面的A小於n個或者多出來的A比前面的B少,就放A。用min(m,j)是因爲最多前面放m個B,當i爲n時且前面沒有B時就不能再放A了
5.j個B時同理,組成的BA小於m或者前面的B比A少時就放B
下附狀態轉移方程
dp[0][0] = 1;
for(int i = 0; i <= n+m; ++i)
for(int j = 0; j <= m+n; ++j)
{
if(i < n || (i-n) < min(m,j))
dp[i+1][j] = (dp[i+1][j] + dp[i][j])%mod;
if(j < m || (j-m) < min(n,i))
dp[i][j+1] = (dp[i][j+1] + dp[i][j])%mod;
}
歡迎指出錯誤qwq
dp殺我!