題目鏈結
題目大意:第一象限內有\(n\)個點(\(n \leq 18\)),求最少要多少條形如\(y=ax^2+bx \quad a<0,a,b, \in r\) 的拋物線才能覆蓋所有點狀壓\(dp\)
分析:\(n\)的資料範圍很小,因此我們可以考慮狀壓\(dp\),填表法不好做我們可以用刷表法
用\(f[s]\)表示覆蓋集合\(s\)內點的最小代價
顯然\(f[0]= 0\)
\(f[s|line[i][j]] = min\\)其中\(line[i][j]\)表示經過\(i,j\)兩點的拋物線可以覆蓋的點的集合
\(f[s | 1<
這樣單次複雜度\(o(2^nn^2)\),有點懸
狀態的\(2^n\)不能消掉我們從轉移入手
原來每次列舉所有沒有被覆蓋的點是\(n^2\)的,我們固定其中乙個點為沒有被覆蓋的點中編號最小的,這樣轉移就是\(n\)的
為什麼這樣是對的?因為我們最終要求的是覆蓋所有的點,當前狀態不覆蓋最小的點也會被下乙個狀態覆蓋,所以可以直接欽定乙個點
這題樣例都卡精度,醉了
#include #include #include #include using namespace std;
const int maxn = 23;
typedef long double type;
const type eps = 1e-7;
struct posval[maxn];
int t,n,m,dp[1 << maxn],lowbit[1 << maxn],line[maxn][maxn];//lowbit表示最小的為0的點的編號
inline bool cmp(type a,type b)
void gauss(type &x,type &y,type a1,type b1,type c1,type a2,type b2,type c2)
inline void solve()
for(int i = 0;i < 1 << n;i++)
cout << dp[(1 << n) - 1] << '\n';
}int main()
cin >> t;
while(t--)solve();
return 0;
}
P2831 憤怒的小鳥 題解
p2831 憤怒的小鳥 我們注意到 n 18 所以考慮狀壓 dp或者暴力。定義 f s 表示 s 為 1 位置上的豬已經被打掉的最少次數 顯然我們能很容易的得到轉移方程 dp 0 0 dp s line i j min dp s 1 dp s 1 i 1 min dp s 1 考慮如何優化 因為我們...
P2831 憤怒的小鳥
kiana最近沉迷於一款神奇的遊戲無法自拔。簡單來說,這款遊戲是在乙個平面上進行的。有一架彈弓位於 0,0 處,每次kiana可以用它向第一象限發射乙隻紅色的小鳥,小鳥們的飛行軌跡均為形如y ax 2 bxy ax2 bx的曲線,其中a,b是kiana指定的引數,且必須滿足a 0。當小鳥落回地面 即...
P2831 憤怒的小鳥
傳送門 看到資料範圍就知道是搜尋或狀壓dp 算了一波複雜度搜尋好像過不了極限資料 搞狀壓設 f i 表示所有豬的狀態為 i 二進位制下1表示死了,0表示沒死 時需要的最少發射次數 設 p i j 存經過第 i 只豬和第 j 只豬的拋物線經過的豬的狀態 可以 n 2 預處理出來,解方程都會吧.找到第乙...