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;
    }
}
}

 

 

 

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