使用過android手機的同學一定對手勢解鎖螢幕不陌生。android的解鎖螢幕由3x3個點組成,手指在螢幕上畫一條
線將其中一些點連線起來,即可構成乙個解鎖圖案。如下面三個例子所示:
畫線時還需要遵循一些規則
1.連線的點數不能少於4個。也就是說只連線兩個點或者三個點會提示錯誤。
2.兩個點之間的連線不能彎曲。
3.每個點只能"使用"一次,不可重複。這裡的"使用"是指手指劃過乙個點,該點變綠。
4.兩個點之間的連線不能"跨過"另乙個點,除非那個點之前已經被"使用"過了。
對於最後一條規則,參見下圖的解釋。左邊兩幅圖違反了該規則:而右邊兩幅圖(分別為2→4→1→3→6和→5→4→1→9→2)
則沒有違反規則,因為在"跨過"點時,點已經被"使用"過了。
現在工程師希望改進解鎖螢幕,增減點的數目,並移動點的位置,不再是乙個九宮格形狀,但保持上述畫線的規則不變。
請計算新的解鎖螢幕上,一共有多少滿足規則的畫線方案。
輸入檔案第一行,為乙個整數n,表示點的數目。
接下來n行,每行兩個空格分開的整數xi和yi,表示每個點的座標。
-1000≤xi,yi≤l000,1≤n<20。各點座標不相同
輸出檔案共一行,為題目所求方案數除以100000007的餘數。 4
0 01 1
2 23 3
8解釋:設4個點編號為1到4,方案有1→2→3→4,2→1→3→4,3→2→1→4,2→3→1→4,
及其映象4→3→2→1,3→4→2→1,2→3→4→1,3→2→4→1.
solution
很明顯的狀壓dp,記 f[i][s] 為最後走到 i 時,狀態為 s 的方案數。預處理從 i 走到 j 需要先走的點的集合。
然後從小到大列舉狀態dp就可以了。
code
#include #include #define r register
#define ll long long
using namespace std;
namespace dntcry
const int maxn = 1010, mod = 100000007;
int n, x[21], y[21], need[21][21], f[21][1 << 19], lim, ans;
bool check(r int s)
int min(r int a, r int b)
int max(r int a, r int b)
bool atline(r int a, r int b, r int c)
int main()
}printf("%d\n", ans);
return 0; }}
int main()
CQOI2018 解鎖螢幕
其實只有開了o2才能a.就是我們看到n的範圍這麼小,就想到狀壓dp。然後我們設狀態dp i 表示狀態為i的 二進位制表示該點選或者不選 方案數有多少個。但是我們發現因為還要列舉轉移下乙個點,所以我們還要記錄一下最後的那個點是什麼。於是我們修改狀態為 dp i j 表示當前狀態為i,最後乙個點的編號為...
CQOI 2018 解鎖螢幕
洛谷傳送門 使用過android 手機的同學一定對手勢解鎖螢幕不陌生。android 的解鎖螢幕由3x3 個點組成,手指在螢幕上畫一條線,將其中一些點連線起來,即可構成乙個解鎖圖案。如下面三個例子所示 畫線時還需要遵循一些規則 連線的點數不能少於4 個。也就是說只連線兩個點或者三個點會提示錯誤。兩個...
CQOI2018 解鎖螢幕
n leq 20 一眼狀壓。設 f i j 表示 訪問狀態為 i 當前在 j 點的方案數。我們列舉乙個 k 表示下乙個要去的地方 要判斷 j 能不能轉移到 k 還要列舉 l 判斷 j,k,l 是否共線。判斷共線是基礎向量,一次點積 一次叉積帶走。這樣複雜度 o n 32 n 期望得分 30 incl...