狀壓dpn≤18\text
dp
n\leq 18
n≤18
,不是暴搜就是狀壓,因為我jio
jioji
o得狀壓會比較好理解,所以就寫一篇狀壓的題解叭
首先我們要預處理出經過任意兩點的拋物線可以擊中的小豬有哪些,可以用lin
e[i]
[j
]line[i][j]
line[i
][j]
來表示經過i,j
i,ji,
j的拋物線經過的小豬的集合,集合用二進位制數來表示
處理完之後就要想一想如何dp
\text
dp我們設dp[
s]
dp[s]
dp[s
]表示消滅集合s
ss內所有小豬所用的最少的小鳥數
顯然d p[
0]=0
dp[0]=0
dp[0]=
0,因為沒有豬當然用不到鳥
假設當前的狀態為s
ss,拋物線為經過i,j
i,ji,
j點的拋物線,這條拋物線打掉的小豬的狀態為lin
e[i]
[j
]line[i][j]
line[i
][j]
,那麼有
d p[
s∣li
ne[i
][j]
]=
min(d
p[s∣
line
[i][
j]],
dp[s
]+1)
dp[s|line[i][j]] = \min(dp[s|line[i][j]],dp[s] + 1)
dp[s∣l
ine[
i][j
]]=min(d
p[s∣
line
[i][
j]],
dp[s
]+1)
其中s ∣l
ine[
i][j
]s|line[i][j]
s∣line
[i][
j]表示當前狀態s
ss在增加了經過i,j
i,ji,
j點的這條拋物線之後能打到的小豬的集合,顯然要從dp[
s∣li
ne[i
][j]
]dp[s|line[i][j]]
dp[s∣l
ine[
i][j
]]和d p[
s]+1
dp[s]+1
dp[s]+
1中取最小
時間複雜度o(t
n22n
)o(tn^22^n)
o(tn22
n)o(能過才怪),在洛谷上吸氧(o2o2
o2)可以過
隨意選擇s
ss內的乙隻小豬j
jj,那麼j
jj最後一定會被乙隻小鳥消滅,所以我們固定住這只小豬j
jj,只列舉k
kk轉移
更詳細見athousandsuns的題解
時間複雜度o(t
n2n)
o(tn2^n)
o(tn2n
),穩了
/*
author:loceaner
*/#include
#include
#include
#include
#include
#define eps (1e-6)
using
namespace std;
const
int a =
5e5+11;
const
int b =
1e6+11;
const
int mod =
1e9+7;
const
int inf =
0x3f3f3f3f
;inline
intread()
int n, m, num, line[20]
[20], dp[b]
;struct pig p[a]
;//豬豬結構體
bool
cmp(pig a, pig b)
struct line };
inline line get
(pig a, pig b)
intmain()
int u =(1
<< n)-1
;//全集
dp[0]
=0;//沒豬當然是0
for(
int i =
1; i <= n; i++
)//快樂地dp吧!
for(
int j =
1; j <= n; j++
)for
(int k =
0; k <= u; k++
) dp[k | line[i]
[j]]
=min
(dp[k | line[i]
[j]]
, dp[k]+1
);cout << dp[u]
<<
'\n';}
return0;
}
/*
author:loceaner
*/#include
#include
#include
#include
#include
#define eps (1e-6)
using
namespace std;
const
int a =
5e5+11;
const
int b =
1e6+11;
const
int mod =
1e9+7;
const
int inf =
0x3f3f3f3f
;inline
intread()
int n, m, num, line[20]
[20], dp[b]
, must[b]
;struct pig p[a]
;bool
cmp(pig a, pig b)
struct line };
inline line get
(pig a, pig b)
intmain()
int t =
read()
;while
(t--
)int u =(1
<< n)-1
; dp[0]
=0;for
(int i =
0; i <= u; i++
) cout << dp[u]
<<
'\n';}
return0;
}
洛谷 P2831 憤怒的小鳥
kiana最近沉迷於一款神奇的遊戲無法自拔。簡單來說,這款遊戲是在乙個平面上進行的。有一架彈弓位於 0,0 處,每次kiana可以用它向第一象限發射乙隻紅色的小鳥,小鳥們的飛行軌跡均為形如 當小鳥落回地面 即x軸 時,它就會瞬間消失。在遊戲的某個關卡裡,平面的第一象限中有n只綠色的小豬,其中第i只小...
洛谷p2831憤怒的小鳥
原題 每個豬的位置不同,所以不能簡單的表示出狀態,all i 表示第i個拋物線打掉了哪些豬,其值本身儲存狀態 二進位制 只需要找所有有用的拋物線,然後狀壓f i 表示i狀態下最少用掉的鳥,轉移方程見 其中的m可以用來優化。雖然長,但是比較好懂。include include include incl...
洛谷P2831 憤怒的小鳥
題目 狀壓dp。直接列舉二進位制數表示當前豬有沒有被消滅的狀態。最終答案的幾條拋物線必定至少撞到乙個豬。而且兩頭豬確定一條拋物線,可以列舉兩頭豬,分別求出他們的拋物線所消滅豬的狀態,然後可以用類似揹包的方法轉移dp。有方程 dp i 當前拋物線的狀態 min dp i 當前拋物線的狀態 dp i 1...