zoukankan      html  css  js  c++  java
  • 2015多校第6场 HDU 5355 Cake 贪心,暴力DFS

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5355

    题意:给你n个尺寸大小分别为1,2,3,…,n的蛋糕,要求你分成m份,要求每份中所有蛋糕的大小之和均相同,如果有解,输出“YES”,并给出每份的蛋糕数及其尺寸大小,否则输出“NO”

    例如n=5,m=3,即大小尺寸分别为1,2,3,4,5的5个蛋糕,要求分成三份,那么解可以是第一份一个蛋糕,大小为5;第二份两个蛋糕,大小为1、4;第三份两个蛋糕,大小为2、3。这样每份大小之和均为5,满足题目要求。

    解法:首先得放一下这个题解:http://blog.csdn.net/queuelovestack/article/details/47321211 写的很好,这个问题的关键点在于判断出有合法方案时,我们可以将这些蛋糕按照2*m为单位一组一组的分配,每个人拿当前这组的最大最小,次大次小。。。

    然后做完这个过程直到剩余[0,4*m],这个看代码就知道了。对于这个区间的值就直接爆搜即可。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+10;
    typedef long long LL;
    vector <int> ans[15];
    LL sumv[15], cake[maxn];
    bool vis[maxn];
    LL n, m, dis, res;
    //[0-4*m]的DFS
    
    bool dfs(int cur, int sum, int pos)
    {
        if(cur == m+1) return true;
        for(int i=res; i>=pos; i--){
            if(vis[i]) continue;
            if(sum+i==dis){
                cake[i]=cur;
                vis[i]=1;
                if(dfs(cur+1,0,1)) return true;
                vis[i]=0;
                return false;
            }
            else if(sum+i<dis){
                cake[i]=cur;
                vis[i]=1;
                if(dfs(cur,sum+i,i+1)) return true;
                vis[i]=0;
            }
        }
        return false;
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--){
            scanf("%lld%lld", &n,&m);
            memset(sumv, 0, sizeof(sumv));
            memset(vis, false, sizeof(vis));
            memset(cake, 0, sizeof(cake));
            for(int i=0; i<=m; i++){
                ans[i].clear();
            }
            LL sum = n*(n+1)/2;
            if(sum%m!=0){
                puts("NO");
                continue;
            }
            LL ave = sum/m;
            if(ave < n){
                puts("NO");
                continue;
            }
            puts("YES");
            res = n%(2*m);
            //23%(12)=11
            if(res!=0){
                res += 2*m;
                //res=11+12=23
                res = min(res, n);
            }
            //
            //23 6
            int a,b;
            for(int i=n; i>res; i-=(2*m)){
                for(int k=1; k<=m; k++){
                    a=i-k+1,b=i-(2*m)+k;//
                    //23 12
                    //22 13
                    //...
                    ans[k].push_back(a);
                    ans[k].push_back(b);
                    sumv[k]+=a, sumv[k]+=b;
                }
            }
            dis = ave - sumv[1];
            dfs(1, 0, 1);
            for(int i=1; i<=res; i++){
                ans[cake[i]].push_back(i);
            }
            for(int i=1; i<=m; i++){
                int sz = ans[i].size();
                printf("%d", sz);
                for(int j=0; j<sz; j++){
                    printf(" %d", ans[i][j]);
                }
                puts("");
            }
        }
        return 0;
    }
    
  • 相关阅读:
    每日日报2021 3/14
    每日日报2021 3/13
    每日日报2021 3/12
    每日日报2021 3/11
    每日日报2021 3/10
    每日日报2021 3/9
    1678. Goal Parser Interpretation
    1694. Reformat Phone Number
    Amicable Pair (相亲数)
    454. 4Sum II
  • 原文地址:https://www.cnblogs.com/spfa/p/7354809.html
Copyright © 2011-2022 走看看