方磚問題(動態規劃)

Problem A: 方磚問題

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 6  Solved: 2
[Submit][Status][Web Board]

Description

用邊長小於N的正方形方磚(注意,不要求所有的方磚大小相同,請看樣例說明)不重疊地鋪滿N*N的正方形房間,最少要幾塊方磚。

可以將n*n的大正方形分成若干的小矩形,然後對每一個小矩形遞歸地求解,但是分塊方法應該具有普遍性,而且分塊數目應該儘量地少。最好的情況莫過於將正方形分成兩塊,對於這道題,我們可以考慮將正方形分成n*k和n*(n-k)的兩塊小矩形,每一塊都恰好被邊長小於n的正方形以最優的方式填滿(即數目最小的填充方式)。使用動態規劃法,可得遞歸方程爲: 


 
問要鋪滿邊長爲N的正方形,需幾種方磚,使得方磚塊數最少。

Input

第一行是一個整數T,表示測試數據的組數,接下來的T 行,每一行是一個N(2<=N<=100)


Output

對於每一組測試數據輸出一行,爲最少需要的塊數。


Sample Input

2 
4 
5

Sample Output

4 
8

HINT

最優的鋪磚方法


AABBAABBCCDDCCDD


A,B,C,D爲四塊方磚的代號。


其他的鋪法,例如:


AAABAAACAAADEFGH


需要的8塊磚,不是最少的。


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define infinity 0x3f3f3f3f
using namespace std;
int a[104][105];
int slove(int  n)
{
    int i,j,k,t,mins;
    memset(a,0,sizeof(a));
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(i==j&&i!=n)
            {
                a[i][j]=1;
            }
            else
            {
                mins=infinity;
                if(i<j)
                {
                   for(k=j/2;k<=j-1;k++)
                    {
                        mins=min(mins,a[k][i]+a[j-k][i]);
                    }
                }
                else
                {
                    for(k=i/2;k<=i-1;k++)
                    {
                        mins=min(mins,a[k][j]+a[i-k][j]);
                    }
                }
                a[j][i]=a[j][i]=mins;
            }
        }
    }
    return a[n][n];
}
int main()
{
    int t,n;
    cin>>t;
    while(t--)
    {
        cin>>n;
        cout<<slove(n)<<endl;
    }
}

發佈了4 篇原創文章 · 獲贊 22 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章