CQOI 2018 解鎖螢幕

2022-03-20 04:57:50 字數 2385 閱讀 3382

洛谷傳送門

使用過android 手機的同學一定對手勢解鎖螢幕不陌生。android 的解鎖螢幕由3x3 個點組成,手指在螢幕上畫一條線,將其中一些點連線起來,即可構成乙個解鎖圖案。如下面三個例子所示:

畫線時還需要遵循一些規則:

連線的點數不能少於4 個。也就是說只連線兩個點或者三個點會提示錯誤。

兩個點之間的連線不能彎曲。

每個點只能「使用」一次,不可重複。這裡的「使用」是指手指劃過乙個點,該點變綠。

兩個點之間的連線不能「跨過」另乙個點,除非那個點之前已經被「使用」過了。

對於最後一條規則,參見下圖的解釋。左邊兩幅圖違反了該規則; 而右邊兩幅圖(分別為2->4-1-3-6 和6->5-4->1->9-2) 則沒有違反規則,因為在「跨過」點時,點已經被「使用」過了。

現在工程師希望改進解鎖螢幕,增減點的數目,並移動點的位置,不再是乙個九宮格形狀,但保持上述畫線的規則不變。請計算新的解鎖螢幕上,一共有多少滿足規則的畫線方案。

輸入檔案第一行,為乙個整數n,表示點的數目。

接下來n 行,每行兩個空格分開的整數x_ix**i 和y_iy**i,表示每個點的座標。

輸出檔案共一行,為題目所求方案數除以100000007 的餘數。

輸入 #1複製

輸出 #1複製

輸入 #2複製

輸出 #2複製

樣例#1解釋: 設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。

對於30%的資料,1≤n≤101≤n≤10

對於100%的資料,-1000≤x_i,y_i≤1000,1≤n<20−1000≤x**i,y**i≤1000,1≤n

<20。各點座標不相同

七哥@littleseven 推薦的題。必須要做

看到方案數想到遞推,然後\(1\le n\le 20\)。所以想到狀態壓縮。然後七哥讓我推狀態。我一想,如果開多維的話可能空間會爆,所以考慮只開一維,壓成乙個\(1的狀態,表示每個點是否被連線。

後來發現沒法轉移。所以考慮再開一維,於是到處搜尋...拿什麼做第二維能保證既能轉移又不會掛空間呢?

一看資料範圍,只有點數的二十還符合第二點要求,所以就選擇這個做狀態。苦思冥想看完題解之後,覺得把狀態設定成這樣最合適:

\(dp[i][j]\)表示點的選擇狀況為\(i\)、選擇的點集中終點為\(j\)時的方案數。

那麼,針對於乙個已定的狀態\(i\),它能轉移的物件是這個狀態中不為1的點。

舉例:\(dp[10010][2]\)可以轉移到\(dp[11010][4],dp[10011][1]\)等狀態。我們在轉移的時候判一下這個點可不可以轉移即可。(條件是轉移前的\(j\)和轉移後的\(j\)連上的直線上所有的點全部已經被到達過)

這樣的話,我們可以先把兩點間的點開\(vector\)存下,然後進行遞推。

發現只連乙個點的方案數是1.這個當初值。

我們轉移的時候記錄把當前狀態用\(st\)記錄下來,然後再用\(k\)列舉上一層狀態,如果符合條件(即上面的點都被經過了,用\(flag\)標記判斷進行轉移就好)

轉移方程是:

\[dp[st][j]=(dp[st][j]+dp[i][k])\quad(mod\,\,\,p)

\]完整**就是:

#include#include#includeusing namespace std;

const int mod=1e8+7;

int n;

bool flag;

int dp[1<<20][21];

struct node

a[21];

bool cmp(node a,node b)

int lowbit(int x)

return ret;

}int main()

if(flag)

continue;

dp[st][j]=(dp[st][j]+dp[i][k])%mod;}}

int ans=0;

for(int i=0;i

printf("%d",ans);

return 0;

}

CQOI2018 解鎖螢幕

使用過android手機的同學一定對手勢解鎖螢幕不陌生。android的解鎖螢幕由3x3個點組成,手指在螢幕上畫一條 線將其中一些點連線起來,即可構成乙個解鎖圖案。如下面三個例子所示 畫線時還需要遵循一些規則 1 連線的點數不能少於4個。也就是說只連線兩個點或者三個點會提示錯誤。2 兩個點之間的連線...

CQOI2018 解鎖螢幕

其實只有開了o2才能a.就是我們看到n的範圍這麼小,就想到狀壓dp。然後我們設狀態dp i 表示狀態為i的 二進位制表示該點選或者不選 方案數有多少個。但是我們發現因為還要列舉轉移下乙個點,所以我們還要記錄一下最後的那個點是什麼。於是我們修改狀態為 dp i j 表示當前狀態為i,最後乙個點的編號為...

CQOI2018 解鎖螢幕

n leq 20 一眼狀壓。設 f i j 表示 訪問狀態為 i 當前在 j 點的方案數。我們列舉乙個 k 表示下乙個要去的地方 要判斷 j 能不能轉移到 k 還要列舉 l 判斷 j,k,l 是否共線。判斷共線是基礎向量,一次點積 一次叉積帶走。這樣複雜度 o n 32 n 期望得分 30 incl...