NYOJ_546_Divideing Jewels

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
using namespace std;
#define INF 0x80000000
int re[15];
bool dp[100006];
int main()
{
 int t=1,i,j,k,ans;
 while(~scanf("%d",&re[1]))
 {
     ans=re[1];
 for(i=2;i<11;++i)
 {
         scanf("%d",&re[i]);
         if(re[i]) ans+=re[i]*i; //ans表示总的珠宝值,它的一半代表可以平分的数
 }

 if(ans==0) break;
 if(ans&1) {
     printf("#%d:Can't be divided.\n\n",t++);
     continue;
 }
 ans>>=1;
 dp[0]=1; 
 for(i=1;i<=ans;++i)//初始化,假设这里的每一个数都不可以划分
    dp[i]=0;
  for(i=1;i<11;++i)
    for(k=ans;k>=i;--k)
    {
         if(dp[ans]) break; //这句话不加也行,加了又省了几百ms
        for(j=1;j<=re[i]&&k>=j*i;++j) //多重背包
          {
               dp[k]=dp[k-j*i]?1:0; //再说一次,条件表达式是最省时间的,dp[k]表示k容量的背包是否能装满
          }
    }
          if(dp[ans])
               printf("#%d:Can be divided.\n\n",t++);
          else  printf("#%d:Can't be divided.\n\n",t++);
 }
 return 0;
}     

 DFS版本别人的代码:

 
#include<stdio.h>
#include<string.h>
int a[15];
bool dfs(int n,int money){
    if(n==0||money==0){
        if(money==0)
            return true;
    }else{
        for(int i=a[n];i>=0;i--)
            if(money>=n*i&&dfs(n-1,money-n*i)) return true;
    }
    return false;
}
int main()
{
    int i,sum,T=0;
    while(1){
        for(sum=0,i=1;i<=10;i++){
            scanf("%d",&a[i]);
            sum+=i*a[i];
        }
        if(sum==0) break;
        if(sum&1) printf("#%d:Can't be divided.\n",++T); 
        else{
            if(dfs(10,sum>>1)) printf("#%d:Can be divided.\n",++T);
            else printf("#%d:Can't be divided.\n",++T);
        }
    }
    return 0;
}         

 

posted @ 2013-05-04 19:58  小仪在努力~  阅读(295)  评论(0编辑  收藏  举报