LGOJP2831 憤怒的小鳥

2022-02-28 14:28:52 字數 972 閱讀 7566

題目鏈結

資料範圍顯然狀壓/爆搜。

考慮\(f[s]\)表示二進位制下已打了的豬的集合。

可以列舉\(s\)的子集\(s_1\),判定\(s\)中\(s_1\)的補集\(s_2\)是否合法。

判定可以通過待定係數法做到\(o(n)\)判定。若補集合法,則\(f[s]=\min\\)。

複雜度是\(o(tn3^n)\)。這樣能\(70\)分。

考慮如何優化。因為\(n\)很小,所以可以\(o(n^3)\)預處理出\(g_\)表示經過\(i,j\)兩點的二次函式可達的點集。那麼轉移的時候列舉二次函式(通過列舉點\(i\)和點\(j\)),轉移方程\(f[s|g_]=\min\\)。

那麼複雜度降到\(o(tn^22^n)\)。已經可以通過本題了。

唐神的\(blog\)

裡面還有個優化。

乙個結論:每個狀態\(s\)用於轉移的二次函式,一定經過該狀態中不包含的第乙個點\(x\)。因為最後的目標是選所有的點,這個點不選,在最後的最優方案中也一定會被其他點選到,而前面已經處理出了\(g_\),可達點集已經都處理出來了。所以只用這個點\(x\)轉移是合法的。

如果預處理出來每個狀態\(s\)所對應的\(x\)的話複雜度就是\(o(tn2^n)\)的。如果不處理的話會慢一點但也不會太多。

#include using namespace std;

const int n = 20;

const int inf = 0x3f3f3f3f;

const double eps = 1e-10;

int n, m, f[(1 << 18) + 5], t, g[n][n];

double a[n], b[n];

int main()

} for(int s = 0; s < 1 << n; ++s)

}} printf("%d\n", f[(1 << n) - 1]);

}}

luoguP2831 憤怒的小鳥

題目描述 kiana最近沉迷於一款神奇的遊戲無法自拔。簡單來說,這款遊戲是在乙個平面上進行的。有一架彈弓位於 0,0 處,每次kiana可以用它向第一象限發射乙隻紅色的小鳥,小鳥們的飛行軌跡均為形如y ax 2 bxy ax 2 bx的曲線,其中a,b是kiana指定的引數,且必須滿足a 0。當小鳥...

洛谷 2831 憤怒的小鳥

題目描述 kiana 最近沉迷於一款神奇的遊戲無法自拔.簡單來說,這款遊戲是在乙個平面上進行的。有一架彈弓位於 0,0 處,每次 kiana 可以用它向第一象限發射乙隻紅色的小鳥,小鳥們的飛行軌跡均為形如 y ax2 bx 的曲線,其中 a,b 是kiana 指定的引數,且必須滿足 a 0,a,b ...

P2831 憤怒的小鳥

kiana最近沉迷於一款神奇的遊戲無法自拔。簡單來說,這款遊戲是在乙個平面上進行的。有一架彈弓位於 0,0 處,每次kiana可以用它向第一象限發射乙隻紅色的小鳥,小鳥們的飛行軌跡均為形如y ax 2 bxy ax2 bx的曲線,其中a,b是kiana指定的引數,且必須滿足a 0。當小鳥落回地面 即...