世界名画陈列馆问题(分支限界法)

本文详细介绍了如何运用分支限界法来解决世界名画陈列馆的布局优化问题,通过代码实现求解最优展示方案,旨在探讨这种算法在艺术展览规划中的应用。

代码:

#include <bits/stdc++.h>
using namespace std;

const int maxn=200;
int m,n;
int ans;
int ans2[maxn][maxn];
struct Node
{
    int set2[maxn][maxn];
    int loc;
    int sum;
    Node(){};
    Node(int _set2[][maxn],int _loc,int _sum)
    {
        for(int i=1; i<maxn; i++)
        {
            for(int j=1; j<maxn; j++)
                set2[i][j]=_set2[i][j];
        }
        loc=_loc;
        sum=_sum;
    };
    friend bool operator <(Node a,Node b)
    {
        return a.sum>b.sum;
    }
};
void solve()
{
    priority_queue<Node>q;
    ans=1e7;
    for(int i=0; i<(1<<n); i++)
    {
        int j=i;
        int sum=0;
        int vis2[maxn][maxn];
        memset(vis2,0,sizeof(vis2));
        for(int s=1; s<=n; s++)
        {
            if(j&1<<(s-1))
            {
                if(vis2[i][s]==0)
                    vis2[1][s]=1;
                if(vis2[1][s-1]==0)
                    vis2[1][s-1]=2;
                if(vis2[1][s+1]==0)
                    vis2[1][s+1]=2;
                if(vis2[2][s]==0)
                    vis2[2][s]=2;
                sum++;
            }
        }
        int t=1;
        q.push(Node(vis2,t,sum));
    }
    while(!q.empty())
    {
        Node u=q.top();
        int loc=u.loc;
        q.pop();
        if(ans<=u.sum) continue;
        if(u.loc==m+1)
        {
            bool flag=false;
            for(int i=1; i<=m&&!flag; i++)
            {
                for(int j=1; j<=n&&!flag; j++)
                    if(u.set2[i][j]==0)
                        flag=true;
            }
            if(flag) continue;
            if(ans>u.sum)
            {
                ans=u.sum;
                for(int i=1; i<maxn; i++)
                {
                    for(int j=1; j<maxn; j++)
                        ans2[i][j]=u.set2[i][j];
                }
                for(int i=1; i<=n; i++)
                {
                    if(ans2[m+1][i]==1)
                    {
                        ans2[m][i]=1;
                        ans++;
                    }
                }

            }
        }
        int sum=0;
        int se2[maxn][maxn];
        memset(se2,0,sizeof(se2));
        for(int i=0; i<=m; i++)
        {
            for(int j=0; j<maxn; j++)
                se2[i][j]=u.set2[i][j];
        }
        for(int i=1; i<=n; i++)
        {
            if(se2[loc][i]==0)
            {
                if(se2[loc][i]!=1)
                    se2[loc][i]=2;
                if(se2[loc+1][i+1]!=1)
                    se2[loc+1][i+1]=2;
                if(se2[loc+1][i-1]!=1)
                    se2[loc+1][i-1]=2;
                if(se2[loc+1][i]!=1)
                    se2[loc+1][i]=1;
                if(se2[loc+2][i]!=1)
                    se2[loc+2][i]=2;
                sum++;
            }
        }
        q.push(Node(se2,u.loc+1,sum+u.sum));
    }
}
int main()
{
    while(~scanf("%d%d",&m,&n))
    {
        if(m==0&&n==0)break;
        memset(ans2,0,sizeof(ans2));
        solve();
        cout<<ans<<endl;
        bool flag=false;
        if(!flag)
        {
            for(int i=1; i<=m; i++)
            {
                for(int j=1; j<=n; j++)
                    if(ans2[i][j]==1)
                    {
                        printf("1 ");
                    }
                    else
                        printf("0 ");
                cout<<endl;
            }
            cout<<endl;
        }
        else
            puts("-1");
    }
    return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值