圧力dpの解

デジタルdpソリューション:

A.特別なチェッカーボード

  • タイトル:\(n \×n \)nチェッカーボードを置きます。いくつかの正方形を配置できません。それらが互いに攻撃するのを防ぐための解決策の総数を求めてください。注:同じ行または列に配置できる車は1台だけです。それ以外の場合、お互いを攻撃します。

  • 分析:

    • まず、同じライン間で攻撃が発生しないようにするために、各ラインが一度に1ラインずつ配置されている限り、ラインごとに1台の車しか存在できません。
    • 次に、各列に車を1つだけ配置できます。どの列に車があるかを記録できる限り、次回はこの列を考慮する必要はありません。
    • 2進数S使用して、車が列に配置されているかどうかを示します。たとえばn=5, S=01101は、1列目、3列目、4列目(低い位置から開始)が車を配置したことを意味します。最終的S=11111、州内の解の数がわかります
    • 定義f[s]は、州sのシナリオ数を表します。\(s \ in [0 \ sim 2 ^ n-1] \)
      • 仮定s=01101、明らかに:f[01101]= f[01100]+f[01001]+f[00101]
      • しかし、現在の場所に障害がある場合はどうなりますか?そのため、再び車を置くときに、現在位置に障害物があるかどうかを判断します。特定の実装については、コードを参照してください。
  • コードの実装:

    #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.非攻撃性

  • 質問の意味:に\(nは\ n倍\)に置くボードnの王を、彼らはお互いを攻撃しないように、種のプログラムの合計数を置きます。王はそれを上、下、左、右、左上、右下、右上、右下、そして近くの8方向のそれぞれのグリッドに攻撃できます。
  • 分析:
    • この質問は、先ほど説明したトウモロコシ畑の例とよく似ています。障害は少なくなりますが、数の制限が増えます。通常、制限がもう1つある場合は、1つの次元の状態を増やします。
    • 王をdp[ i ][ j ][ k ]最初のi 列に配置し状態を jボード上kの計画とする。
    • ステージは明白です。つまり、行ごとに処理できます。最初の行は特別で、前処理できます
    • 判断の矛盾:s現在の行s'が前の行であるとします。
      • 行の競合、つまり隣接することはできません。判断するだけで(s & (s<<1))==0、ゼロ以外は隣接することを意味します。
      • 列の競合:
        • 逆さまの衝突:(s & s')==00でない場合、裁判官は、逆さまの衝突を意味します。
        • 左上の衝突:裁判官((s<<1) & s')==0、そうでない場合は0、衝突について説明します。
        • 右上の衝突:裁判官((s>>1) & s')==0、そうでない場合は0、衝突を説明します。
      • 現在の状態の状態1を判別するには、lowbitを使用します。

おすすめ

転載: www.cnblogs.com/hbhszxyb/p/12710188.html