這段時間做的簡單dp題目(部分)

2021-10-05 11:52:13 字數 4070 閱讀 7893

這些時間vj上做的部分題目

hdu5115

題意:第一行t,t組測試資料,每組資料第一行輸入n表示n匹狼,第二行給出乙個序列表示每匹狼的傷害,第三行給出每匹狼能給周圍狼的傷害增幅,求怎樣打可以得到最小傷害。

思路:區間dp問題dp[i][j]為消滅i到j只狼的代價,列舉k作為最後乙隻被殺死的狼,此時會受到a[k]和b[i-1] b[j+1]的傷害 取最小的即可列出轉移方程:dp[i][j]=min(dp[i][k-1]+dp[k+1][j]+a[k]+b[i-1]+b[j+1])。

**:

#include

#include

#include

#define ll long long

#define inf 0x3f3f3f3f

using

namespace std;

int a[

310]

,b[310

],dp[

310]

[310];

intmain()

}printf

("case #%d:%d\n"

,cas++

,dp[1]

[n]);}

return0;

}

poj3280 cheapest palindrome

題意:給定乙個字串,讓你用最小的代價使它成為乙個回文串

思路:區間dp問題,具體看**

**:

#include

#include

#include

#include

using

namespace std;

int dp[

2020][

2020

], x, y, cost[30]

;char s[

2020];

int n, m;

intmain()

for(

int i =

1; i < m;i++

)for

(int j = i-

1; j >=

0; j--

) cout << dp[0]

[m -1]

<}return0;

}

hdu4632 palindrome subsequence

題意:找乙個字串裡有多少個回文子串行

思路:區間dp問題,找回文子串行,i到j區間內的種類數可以由i+1 - j和i - j-1這兩步推,但是在這乙個步驟中i+1 - j-1 這段區間重複了兩次,需要減去;如果i和j點的字母相同的話,意味著這兩個點符合回文,所以直接考慮i+1 - j-1這個區間。具體看**

**:

#include

#include

#include

#include

#include

#include

using

namespace std;

#define inf 0x3f3f3f3f

#define mod 10007

int dp[

1010][

1010];

char s[

1010];

intmain()

printf

("case %d: %d\n"

,cas++

,dp[0]

[len-1]

);}return0;

}

zoj3623 battle ships

題意:多組測試資料,第一行輸入戰艦種類數n,防禦塔生命l,下面n行每行輸入生產時間和傷害,問玩家擊毀防禦塔的最少時間

思路:這是乙個完全揹包問題,dp時間,dp[i]表示i秒之前最大傷害,套一下完全揹包模板就可以。

**:

#include

#include

#include

#include

#include

using

namespace std;

int dp[

10010];

int t[

10010

],p[

10010];

intmain()

}return0;

}

hdu3466 proud merchants

題意:多組測試資料,第一行輸入物品數目n和擁有金錢數目m,後面n行每行輸入**p、要買的最少擁有金錢q,價值v,求能買最大價值。

思路:一道蠻好的01揹包題目,有個點在於排序,因為他有限定條件需要錢數大於q才能買,所以要先排序,按照q-p排序,為啥要按照這個,首先看,假設a物品p1,q1,v1,,b物品p2,q2,v2,先買a物品的話你需要p1+q2塊錢,先買b的話需要p2+q1塊錢,如果先買a需要的錢少的話就有這麼乙個式子p1+q2<=p2+q1,然後移項的p1-q1<=p2-q2,這時候就能看出到底應該怎樣排序了。

**:

#include

#include

#include

#include

using

namespace std;

int dp[

10010];

struct node

a[1010];

bool

cmp(nodea,node b)

intmain

(void

)return0;

}

hdu 1114 piggy bank

題意:t組測試資料,存錢罐可以往裡面放一些價值小的錢,給出空罐子的重量和最滿能裝到多重,然後給出每種硬幣的價值和重量,我們要在不打破它的情況下確認罐子裡最少有多少錢。

#include

#include

#include

using

namespace std;

#define inf 0x3f3f3f3f

#define maxn 10010

int dp[

10010];

//dp[i]表容量為i的時候所裝東西的最小價值

intmain()

if(dp[w2-w1]

==inf)

printf

("this is impossible.\n");

else

printf

("the minimum amount of money in the piggy-bank is %d.\n"

,dp[w2-w1]);

}return0;

}

hdu1171 big event in hdu

題意:多組測試資料,n<=0結束輸入,每組樣例先輸入乙個n表示物品種類,後面n行每行給出物品價值和數目,求怎樣把這些物品分成兩半,使這兩半物品的價值差最小。

思路:這道題可以看成01揹包來做,可以直接從總價值/2開始dp,01揹包的模板稍微變一下型就可以

**:

#include

#include

#include

#include

#include

using

namespace std;

int v[

1008611];

//價值

int num[

1008611];

//數目

int dp[

1008611];

intmain()

c = sum/2;

//總價值的一半

/*下面是01揹包做法,套一下模板即可*/

for(

int i=

0;i)for

(int k=

0;k;k++

)for

(int j=c;j>=v[i]

;j--

) dp[j]

=max

(dp[j]

,dp[j-v[i]

]+v[i]);

cout<<<

" "<<}}

這段時間的隨想

blog是乙個很讓人後怕的東西,因為是blog是日誌,當時開通的時候就是想要記得要常常來更新。做事的方法中有一條規則是堅持,這是很難實現的一條規則,如果做到這條規則,成功就實現了一半。於是突然看看上次寫日誌的時間是上個月的23號,今天是7月7號,就很責備自己,怎麼這麼長時間都沒來寫blog呢。然後又...

某次做dp題

問題描述 在一圓形操場四周擺放n 堆石子,現要將石子有次序地合併成一堆.規定每次只能選相鄰的 兩堆合併成一堆,並將新的一堆的石子數,記為該次合併的得分。編一程式,由檔案讀入堆數n 及每堆石子數,1 選擇一種合併石子的方案,使得做n 1 次合併,得分的總和最少 2 選擇一種合併石子的方案,使得做n 1...

這段時間的專案心得

這段時間一直在公司研究現實專案,不敢說收穫,只是從中覺察出自己存在的很多問題!大凡專案總離不開增刪改查,但是往常的練習僅限於單錶或兩個三個表,突然表多了就自亂了陣腳!說說struts2,這個框架怎麼用呢?在前台頁面找到提交action,然後在配置檔案裡找到對應的action實現類,再找到對應的處理方...