Shape pressure DP-Mondrian's dream / shortest hamilton path

State pressure DP is simply to compress the state in a binary way.
Specific topics will have different representations.

Mondrian's dream

First analyze this problem. We are now placing small squares on the row. After placing the small squares on the row, there is only one way to place the vertical small squares. therefore! Just ask for the horizontal placement method.

State representation: f[i][j] is the number, i means enumerating to the i-th column, j means how many small squares extend from the previous column, j is expressed in binary, and a bit of 1 means that the current bit has The small square sticks out.
For the state of the dimension j, it is the state pressure DP.

Next, think about the state transition. The
first is that there can be no conflicts, that is, the i-th column and the i-1th column cannot extend a small square at the same time. Here you can use the and (&) operation to determine whether the result is 0.
Second, you need to ensure After solving the small squares protruding from each row, there should be no spaces whose length is counted in the current column, because vertical squares need to be placed. Here you can use the or (|) operation to determine whether there is a continuous odd number of 0s.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=15,M=1<<N;
int n,m;
ll f[N][M];
bool st[M];
int main()
{
    
    
    while(cin>>n>>m&&n!=0&&m!=0)
    {
    
    
        memset(f,0,sizeof(f));
        //预处理过程,处理出当前过程是否满足放完横向方块后纵向不存在奇数个连续0
        for(int i=0;i<1<<n;i++)
        {
    
    
            st[i]=1;
            int cnt=0;
            for(int j=0;j<n;j++)
            {
    
    
                if(i>>j&1)
                {
    
    
                    if(cnt&1) st[i]=0;
                    cnt=0;
                }
                else cnt++;
            }
            if(cnt&1) st[i]=0;
        }
        //DP过程
        f[0][0]=1; //最开始的时候什么都没发放,这也是一种放法
        for(int i=1;i<=m;i++) //枚举每一列
            for(int j=0;j<1<<n;j++) //枚举当前列的每一个状态
                for(int k=0;k<1<<n;k++) //枚举当前列的前一列的每一个状态
                    if((j&k)==0&&st[j|k]) f[i][j]+=f[i-1][k];
        cout<<f[m][0]<<endl;
    }
    return 0;
}

Shortest hamilton path

The state is expressed as: f[i][j] represents the minimum value, j represents the total point 0 to point j, i represents the point passed from point 0 to point j, and i is expressed in binary. The bit is 1 means that this point has been passed, and 0 means that this point is not passed. The
i dimension is the state compression
state transition: it is quite conventional, which is the same as the shortest path algorithm. First, it facilitates all the points experienced in the current state to the target. The distance between the points, and then take a minimum of these distances

#include <bits/stdc++.h>
using namespace std;
const int N=21,M=1<<N;
int n;
int g[N][N];
int f[M][N];
int main()
{
    
    
    cin>>n;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            cin>>g[i][j];
    memset(f,0x3f,sizeof(f));
    f[1][0]=0; //0号点到0号点自己的距离是0
    for(int i=0;i<1<<n;i++)
        for(int j=0;j<n;j++)
            if(i>>j&1)
                for(int k=0;k<n;k++)
                    if(i>>k&1)
                        f[i][j]=min(f[i][j],f[i-(1<<j)][k]+g[k][j]);
    cout<<f[(1<<n)-1][n-1]<<endl;
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_46126537/article/details/113051449