zoukankan      html  css  js  c++  java
  • 力扣周赛 1723 完成所有工作的最短时间

    题意

    (n) , (k) 和一个长度为 (n) 的数组 (a) ,将 (a) 分成 (k) 组,求 (k) 组里最大值的最小值

    (1 le k le n le 12)

    思路

    这道题目的做法有很多,比较正确的做法是状压dp,也可以用模拟退火来做,也可以用贪心瞎搞 A 过去

    状压dp

    设 f[j][i] 表示前 j 组完成了任务集合 i 的最大值的最小值

    答案就是 f[k-1][(1 << n) - 1], 考虑其转移

    枚举集合 i 的子集 s

    [f[j][i] = min_{sin i}(max{f[j-1][i-s], tot[s]}) ]

    class Solution {
    public:
        int tot[1<<13];
        int f[13][1<<13];
    
        int minimumTimeRequired(vector<int>& jobs, int k) {
            memset(f,0x3f,sizeof f);
            int n = jobs.size();
            for(int i = 0;i < 1 << n;i++){    
                for(int j = 0;j < n;j++){
                    if((i >> j) & 1)tot[i] += jobs[j];
                }
            }
            for(int i = 0;i < (1 << n);i++)f[0][i] = tot[i];
            for(int j = 1;j < k;j++){
                for(int i = 0;i < 1 << n;i++){
                    int minv = 0x3f3f3f3f;
                    for(int s = i;s ;s = (s - 1) & i){
                        minv = min(minv, max(f[j-1][i - s], tot[s]));
                    }
                    f[j][i] = minv;
                }
            }
            return f[k-1][(1<<n) - 1];
    
        }
    };
    

    模拟退火

    参考 HAOI2006 均分数据, 改一改就可以了 , 我的代码

    瞎搞

    贪心的把目前的 (A_i) 加入到最小的 sum 中, 用 random_shuffle 瞎搞个几万次取最小值

    class Solution {
    public:
        
        int cal(vector<int>& jobs, int k){
            int sum[20] = {0};
            for(int v : jobs){
                int idx = 0,mx = 120000000;
                for(int i = 1;i <= k;i++){
                    if(sum[i] < mx){
                        mx = sum[i];
                        idx = i;
                    }
                }
                sum[idx] += v;
            }
            int ans = 0;
            for(int i = 1;i <= k;i++)ans = max(ans,sum[i]);
            return ans;
        }
        int minimumTimeRequired(vector<int>& jobs, int k) {
            int ans = 0x3f3f3f3f;
            int t = 50000;
            while(t--){
                random_shuffle(jobs.begin(),jobs.end());
                ans = min(ans, cal(jobs,k));
            }
            return ans;
        }
    };
    
  • 相关阅读:
    BZOJ3503: [Cqoi2014]和谐矩阵
    不常用的黑科技——「三元环」
    解题:八省联考2018 劈配
    解题:EXNR #1 金拱门
    解题:八省联考2018 林克卡特树
    解题:AT2064 Many Easy Problems&EXNR #1 T3 两开花
    解题:SPOJ 422 Transposing is Even More Fun
    解题:SDOI 2017 硬币游戏
    解题:CTSC 2006 歌唱王国
    解题:BZOJ 3622 已经没有什么好害怕的了·
  • 原文地址:https://www.cnblogs.com/sduwh/p/14291506.html
Copyright © 2011-2022 走看看