zoukankan      html  css  js  c++  java
  • poj 1020 Anniversary Cake

    搜索

    题意:先给出大方阵的边长,再给出m个小方阵并给出每个方阵的边长,问是否可以不发生重叠地把小方阵放进大方阵中,并且大方阵完全利用没有剩余

    这题的代码不难写,关键是要找到策略,这题的策略比搜索本身的剪枝更有价值

    摆放小方阵的策略是,尽可能往上面摆,然后尽可能往左边摆。另外有个策略一开始想错了,我是想先把小方阵排序,先放好大的,再放好小的,这样在摆放过程中可能出问题,画图可知,正确的策略是就目前的摆放情况,能放得到下哪个就放哪个,无所谓大小

    为了满足尽可能放在左上方的条件,需要记录大方针的状态

    col[i]的意义是,第i列,从最顶部数下来,被连续占据了多少格

    注意在整个摆放过程中,每一列都保证是被连续占据的,不会出现断开的情况,这要求在搜索剪枝的时候处理好

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    #define N 55
    #define M 15
    
    int n,m;
    int col[N],s[M];
    
    bool dfs(int mm)
    {
        if(mm >= m) return true;
    
        int Min = N , c = 0;
        for(int i=1; i<=n; i++)
            if(col[i] < Min)
            {
                Min = col[i];
                c = i;
            }
    
        for(int i=1; i<=10; i++)
            if(s[i])
            {
                bool ok = true;
                if( !(c+i-1 <= n && col[c]+i <= n) ) continue;
                for(int k = c; k <= c+i-1; k++)
                    if(col[k] != col[c])
                    { 
                        ok = false; 
                        break; 
                    }
                if(!ok) continue;
                
                s[i]--;
                for(int k=c; k <= c+i-1; k++)
                    col[k] += i;
                if(dfs(mm+1)) return true;
                s[i]++;
                for(int k=c; k <= c+i-1; k++)
                    col[k] -= i;
            }
    
        return false;
    }
    
    int main()
    {
        int cas;
        cin >> cas;
        while(cas--)
        {
            int x,sum = 0;
            cin >> n >> m;
            memset(s,0,sizeof(s));
            for(int i=0; i<m; i++)
            {
                cin >> x;
                s[x]++;
                sum += x * x;
            }
            memset(col,0,sizeof(col));
            if(sum != n * n || !dfs(0)) cout << "HUTUTU!" << endl;
            else                        cout << "KHOOOOB!" << endl;
        }
        return 0;
    }
  • 相关阅读:
    iOS
    UI基本视图控制
    堆和栈的区别 ?
    单例模式
    Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么?
    id
    协议
    分类(类别)
    #import和#include以及@class三者的区别?
    内存管理
  • 原文地址:https://www.cnblogs.com/scau20110726/p/3132878.html
Copyright © 2011-2022 走看看