description
使用過android手機的同學一定對手勢解鎖螢幕不陌生。android的解鎖螢幕由3x3個點組成,手指在螢幕上畫一條input線將其中一些點連線起來,即可構成乙個解鎖圖案。如下面三個例子所示:
畫線時還需要遵循一些規則 1.連線的點數不能少於4個。也就是說只連線兩個點或者三個點會提示錯誤。 2.兩個點之間的連線不能彎曲。
3.每個點只能」使用」一次,不可重複。這裡的」使用」是指手指劃過乙個點,該點變綠。
4.兩個點之間的連線不能」跨過」另乙個點,除非那個點之前已經被」使用」過了。
對於最後一條規則,參見下圖的解釋。左邊兩幅圖違反了該規則:而右邊兩幅圖(分別為2→4→1→3→6和→5→4→1→9→2)
則沒有違反規則,因為在」跨過」點時,點已經被」使用」過了。
現在工程師希望改進解鎖螢幕,增減點的數目,並移動點的位置,不再是乙個九宮格形狀,但保持上述畫線的規則不變。
請計算新的解鎖螢幕上,一共有多少滿足規則的畫線方案。
輸入檔案第一行,為乙個整數n,表示點的數目。 接下來n行,每行兩個空格分開的整數xi和yi,表示每個點的座標。output-1000≤xi,yi≤l000,1≤n<20。各點座標不相同
輸出檔案共一行,為題目所求方案數除以100000007的餘數。sample input
0 0sample output hint1 12 2
3 3
解釋:設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.
好慌只會o(n22n
) o(n
22n)
怎麼辦
然後我就過了。。
你就設f[i][j]表示以i為結尾,狀態為j的方案數
然後再壓乙個go[i][j]表示i想到j必須要選定哪些點,壓起來
瞎轉移
卡卡常就跑的飛快了
#include
#include
#include
#include
#include
using
namespace
std;
const
int mod=100000007;
int bin[22];
int f[25][(1
<<20)+10],go[25][25];
struct ptw[25];
bool findpla(pt n1,pt n2,pt n3)//n3是否在n1->n2中
int n,ans;
int main()
for(register
int i=1;i<=n;i++)f[i][bin[i-1]]=1;
for(register
int j=1;j<=bin[n]-1;j++)
for(register
int i=1;i<=n;i++)if(bin[i-1]&j)
for(register
int k=1;k<=n;k++)if(k!=i &&(bin[k-1]&j)==0 && (j|go[i][k])==j)f[k][j|bin[k-1]]=(f[k][j|bin[k-1]]+f[i][j])%mod;
for(register
int i=0;i<=bin[n]-1;i++)
printf("%d\n",ans);
return
0;}
bzoj 1076(狀壓dp)(期望dp)
傳送門 題解 dp i j 表示第i輪狀態為j 狀態中為1的位表示當前物品還沒被取走 的最大期望得分。為了防止從無效狀態轉移至有效狀態,採用倒推法,從已知的有效狀態往回推,具體注釋在 中。p.s.不寫memset可以快接近一倍,但是為了思維嚴密性,還是寫乙個,反正都能過 注意 由於吃過的寶物可以再吃...
BZOJ 4152 狀壓DP 解題報告
4152 amppz2014 the captain time limit 給定平面上的n個點,定義 x1,y1 到 x2,y2 的費用為min x1 x2 y1 y2 求從1號點走到n號點的最小費用。input 第一行包含乙個正整數n 2 n 200000 表示點數。接下來n行,每行包含兩個整數x...
BZOJ 4197 壽司晚宴 狀壓DP
time limit 10 sec memory limit 512 mb submit 694 solved 440 submit status discuss 為了慶祝 noi 的成功開幕,主辦方為大家準備了一場壽司晚宴。小 g 和小 w 作為參加 noi 的選手,也被邀請參加了壽司晚宴。在晚宴...