zoukankan      html  css  js  c++  java
  • UVA1099----Sharing Chocolate----在集合上的DP

    题目地址:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3540

    题目意思:

    给你一块X*Y的巧克力

    问你是否可以分成N块大小分别为AI的小巧克力

    解题思路:

    我们用F[X][S]表示能否分成将一个小边为X且集合为S

    切的时候分两种,横切和竖切

    横切则是X不变,竖切则是Y不变,可以切成两个子集,按记忆化搜索

    对于那些x*y不等于sum[s]的我们可以直接不计算,因为无法满足,没有计算的必要

    下面上代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 16;
    const int maxs = 1<<maxn;
    const int maxx = 110;
    
    int a[maxn];
    int f[maxx][maxs];
    bool vis[maxx][maxs];
    int sum[maxs];
    int x,y,n;
    int all;
    
    int bitcount(int x)
    {
        return x==0?0:bitcount(x>>1)+(x&1);
    }
    
    int dp(int S,int x)
    {
        if(vis[x][S])
            return f[x][S];
        vis[x][S]=1;
        int &ans = f[x][S];
        if(bitcount(S)==1)
            return ans=1;
        int y = sum[S]/x;
    
        //枚举子集S0
        for(int S0=(S-1)&S;S0;S0=(S0-1)&S)
        {
            int S2 = S-S0;
            if(sum[S0]%x==0 && dp(S0,min(x,sum[S0]/x)) && dp(S2,min(x,sum[S2]/x)))
                return ans = 1;
            if(sum[S0]%y==0 && dp(S0,min(y,sum[S0]/y)) && dp(S2,min(y,sum[S2]/y)))
                return ans = 1;
        }
    
        return ans = 0;
    }
    
    int main()
    {
        int ca = 1;
        while(~scanf("%d",&n) && n)
        {
            memset(sum,0,sizeof(sum));
            scanf("%d%d",&x,&y);
            for(int i=0;i<n;i++)
                scanf("%d",&a[i]);
            for(int s=0;s<(1<<n);s++)
            {
                for(int i=0;i<n;i++)
                {
                    if(s&(1<<i))
                        sum[s]+=a[i];
                }
            }
            all = (1<<n)-1;
            memset(vis,false,sizeof(vis));
            int ans;
            if(sum[all] != x*y || sum[all]%x!=0)
                ans = 0;
            else
                ans = dp(all,min(x,y));
    
            printf("Case %d: %s
    ",ca++,ans?"Yes":"No");
    
        }
        return 0;
    }
    
    


  • 相关阅读:
    Spark Streaming ---没用
    spark-streaming笔记 ---没用
    zookeeper笔记 ---没用
    远程调试笔记 ---没用
    远程仓库
    git之时光机穿梭
    分布式版本控制系统 VS 集中式
    Map与WeakMap
    set与weakset
    Genarator生成器
  • 原文地址:https://www.cnblogs.com/pangblog/p/3244060.html
Copyright © 2011-2022 走看看