Solution numérique dp:
A. Damier spécial
-
Titre: Mettez une voiture sur le damier dans \ (n \ fois n \)
n
, certaines cases ne peuvent pas être placées, et recherchez le nombre total de solutions qui les empêchent de s'attaquer. Remarque: Il ne peut y avoir qu'une seule voiture dans la même ligne ou colonne, sinon ils s'attaqueront mutuellement. -
Analyse:
- Tout d'abord, il ne peut y avoir qu'une seule voiture par ligne, tant que chaque ligne est placée une ligne à la fois pour s'assurer qu'il n'y a pas d'attaque entre la même ligne.
- Deuxièmement, une seule voiture peut être placée dans chaque colonne, tant qu'elle peut enregistrer quelle colonne a une voiture, il ne sera pas nécessaire de considérer cette colonne la prochaine fois.
- Utilisez un nombre binaire
S
pour indiquer si une voiture a été placée dans une colonne. Par exemplen=5, S=01101
, cela signifie que les première, troisième et quatrième colonnes (à partir de la position inférieure) ont placé des voitures. On retrouve enfinS=11111
le nombre de solutions en l'état . - La définition
f[s]
représente les
nombre de scénarios dans l'état . \ (s \ dans [0 \ sim 2 ^ n-1] \)- Supposons
s=01101
, évidemment:f[01101]= f[01100]+f[01001]+f[00101]
- Mais qu'en est-il s'il y a un obstacle à l'emplacement actuel? Donc, lorsque nous remettons la voiture, nous jugeons s'il y a un obstacle dans la position actuelle. Voir le code pour une implémentation spécifique.
- Supposons
-
Implémentation du code:
#include<bits/stdc++.h> const int maxn=(1<<20)-1; typedef long long LL; LL f[maxn],a[25];//a[x]记录第x行的障碍状态 int lowbit(int x){return x & -x;}; int main(){ int n,m;scanf("%d%d",&n,&m); for(int i=1;i<=m;++i){ int x,y;scanf("%d%d",&x,&y); a[x]+=1<<(y-1); } f[0]=1;//一个也不放也是一种方案 int maxs=1<<n;//最大的状态 for(int S=1;S<maxs;++S){//从状态1开始枚举 int cnt=0;//计算状态S里的1的个数,几个1说明处理到第几行 for(int i=S;i;i-=lowbit(i))cnt++; for(int i=S;i;i-=lowbit(i)){//依次判断当前状态每一个1 if(!(a[cnt] & lowbit(i))){//状态S当前的1所在列如果没有障碍 int s=S^lowbit(i);//说明lowbit(i)处可以放车,当前就在此处放车 f[S]+=f[s];//s<S,保证能转移 } } } printf("%lld\n",f[maxs-1]); return 0; }
B. Non-agression
- Signification des questions: dans \ (n \ times n \) Conseil qui a mis
n
un roi, afin qu'ils n'attaquent pas, mettre le nombre total de programme espèces. Le roi peut l'attaquer en haut, en bas, à gauche, à droite, en haut à gauche, en bas à droite, en haut à droite, en bas à droite et une grille dans chacune des huit directions à proximité, pour un total de grilles. - Analyse:
- Cette question est très similaire à l'exemple du champ de maïs dont nous avons parlé. Il y a moins d'obstacles, mais la limite de nombre est augmentée. En général, s'il y a une autre limite, nous augmenterons l'état unidimensionnel.
- Que l' état de placement du roi au
dp[ i ][ j ][ k ]
premieri
rang soit lej
nombrek
de plans sur le plateau . - L'étape est évidente, c'est-à-dire que nous pouvons la traiter ligne par ligne, la première ligne est spéciale, nous pouvons prétraiter
- Conflit de jugement: supposez que
s
la ligne actuelles'
est la ligne précédente.- Les conflits de lignes, c'est-à-dire ne peuvent pas être adjacents, il suffit de juger
(s & (s<<1))==0
, non nul signifie qu'il y a adjacent. - Conflit de colonne:
- Conflit à l'envers: juge
(s & s')==0
, sinon 0, cela signifie conflit à l'envers. - Conflit supérieur gauche: juge
((s<<1) & s')==0
, sinon0
, expliquez le conflit. - Conflit supérieur droit: juge
((s>>1) & s')==0
, sinon0
, expliquez le conflit.
- Conflit à l'envers: juge
- Pour déterminer
1
le nombre d'états dans l' état actuel , utilisez lowbit.
- Les conflits de lignes, c'est-à-dire ne peuvent pas être adjacents, il suffit de juger