洛谷P1489 貓狗大戰(布林DP)

2021-08-29 18:30:14 字數 704 閱讀 4748

傳送門

很新穎的乙個布林dp,我們用dp[i][j]表示選i個人能否構成j的血量

注意,是「能否」,也就是說dp存的是乙個邏輯變數。

首先考慮一些細節,對於偶數的n,那麼兩個部隊人數肯定是i/2,對於奇數,為i/2(向下取整)和i/2+1

考慮如何進行狀態轉移,dp[i][j]=dp[i][j] | dp[i-1][j-val[k],這個方程挺像揹包,所以應該沒什麼難度。

多說一句 這份**會被3 1 1 3 hack掉,網上幾乎所有的dp題解都會被hack掉,我一直在思考是哪個細節出了問題,最終無果,望大佬能夠指點一波。

//bool-dp 

#include#define n 205

using namespace std;

int n,val[n],dp[n][n],sum;

int main()

dp[0][0]=true;

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

{for(int j=n/2;j>=1;j--)

{for(int k=sum;k>=val[i];k--)

{dp[j][k]=dp[j][k]|dp[j-1][k-val[i]];

// cout<<"i:"<=0;i--)

{if(dp[n/2][i]==true){

cout<

洛谷P1489 貓狗大戰(布林DP)

傳送門 很新穎的乙個布林dp,我們用dp i j 表示選i個人能否構成j的血量 注意,是 能否 也就是說dp存的是乙個邏輯變數。首先考慮一些細節,對於偶數的n,那麼兩個部隊人數肯定是i 2,對於奇數,為i 2 向下取整 和i 2 1 考慮如何進行狀態轉移,dp i j dp i j dp i 1 j...

洛谷 貓狗大戰

初見安 這裡是傳送門 洛谷p1489 貓狗大戰 乙個挺冷門的題啊 也蠻有意思的。把n個數劃分成兩部分,讓兩部分的數的總和的差值盡量小。其實一眼dp,但是要往正解的方向去想是有點點難度的 明顯我們確定乙個集合,另乙個集合也就可以確定了。思考暴力一點的做法 如果我們可以列舉乙個集合的所有可能性,是不是就...

DP luoguP1489貓狗大戰

題目大意 給你乙個序列 長度小於等於200 你需要把它分成兩半而且兩個被分開的序列長度差不超過一 如果是偶數的話那麼就必須是一樣長咯 要求分成的兩個序列的總和差的絕對值最小 做題思路 1.既然是序列總和,而且分成兩半,那麼我為什麼不先預處理出一開始整個序列的和呢?2.既然是兩個序列的總和,那麼必然會...