ZOJ1149-Dividing

 

#include<iostream>
#include<algorithm>
#include <cstring>
using namespace std;
//P139
//動態規劃
int a[7];//各種價值大理石的塊數
int iCase=1;//測試數據組的編號
int sum=0;//預處理之後大理石的總價值
int i;
void DP(int sum)
{
    int i,j,k;
    //大理石塊總價值的一半
    int mid=sum/2;
    //大理石的狀態數組
    char visit[200];
    memset(visit,0,sizeof(visit));
    int t;
    visit[0]=1;//初值
    //對每種價值的大理石塊
    for(i=1; i<=6; i++)
        for(j=mid; j>=0; j--)
            //價值爲j的分配方案存在
            if(visit[j])
                for(k=1; k<=a[i]; k++)
                {
                    t=j+i*k;
                    if(t>mid)
                        break;
                    //增加k塊價值爲i的大理石,該平分方案仍然成立
                    else
                        visit[t]=1;
                    //找到了分配方案
                    if(t==mid)
                    {
                        cout<<"Can be divided."<<endl;
                        return;
                    }
                }
    cout<<"Can't be divided."<<endl;
}
int main()
{
    for(i=1; i<=6; i++)
    {
        cin>>a[i];
        //數據預處理
        if(a[i]!=0&&a[i]%6==0)
            a[i]=6;
        else
            a[i]=a[i]%6;
        sum+=a[i]*i;
    }
    while(sum!=0)
    {
//當和爲0時說明是輸入結束的標誌
        cout<<"Collection #"<<iCase++<<":"<<endl;
//總價值爲奇數,無法平分
        if(sum%2)
        {
            cout<<"Can't be divided."<<endl;
        }
        else
        {
            DP(sum);
        }
        sum=0;
        for(i=1; i<=6; i++)
        {
            cin>>a[i];
            //數據預處理
            if(a[i]!=0&&a[i]%6==0)
                a[i]=6;
            else
                a[i]=a[i]%6;
            sum+=a[i]*i;
        }
    }
}

平分大理石塊的枚舉算法:

#include<iostream>
#include<algorithm>
using namespace std;
//P139
//枚舉法
int a[7];//各種價值大理石的塊數
int iCase=1;//測試數據組的編號
int sum=0;//預處理之後大理石的總價值
int i;
void enumerate(int sum)
{
    int mid;
    int i1,i2,i3,i4,i5,i6;
    for(i1=0; i1<=a[1]; i1++)
        for(i2=0; i2<=a[2]; i2++)
            for(i3=0; i3<=a[3]; i3++)
                for(i4=0; i4<=a[4]; i4++)
                    for(i5=0; i5<=a[5]; i5++)
                        for(i6=0; i6<=a[6]; i6++)
                        {
                            mid=1*i1+2*i2+3*i3+4*i4+5*i5+6*i6;
                            if(mid==sum/2)
                            {
                                cout<<"Can be divided."<<endl;
                                return;
                            }
                        }
    cout<<"Can't be divided."<<endl;
}
int main()
{
    for(i=1; i<=6; i++)
    {
        cin>>a[i];
        //數據預處理
        if(a[i]!=0&&a[i]%6==0)
            a[i]=6;
        else
            a[i]=a[i]%6;
        sum+=a[i]*i;
    }
while(sum!=0){
//當和爲0時說明是輸入結束的標誌
    cout<<"Collection #"<<iCase++<<":"<<endl;
//總價值爲奇數,無法平分
    if(sum%2)
    {
        cout<<"Can't be divided."<<endl;
    }
    else
    {
        enumerate(sum);
    }
    sum=0;
     for(i=1; i<=6; i++)
    {
        cin>>a[i];
        //數據預處理
        if(a[i]!=0&&a[i]%6==0)
            a[i]=6;
        else
            a[i]=a[i]%6;
        sum+=a[i]*i;
    }
}
}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章