首页 > 其他分享 >Weekly Contest 388

Weekly Contest 388

时间:2024-03-17 16:45:09浏览次数:26  
标签:pre Contest int sum long length 388 dp Weekly

Problem A

Apple Redistribution into Boxes

思路

求和-算所有苹果的和 然后将箱子从大到小排序 贪心即可

代码

class Solution {
    public int minimumBoxes(int[] apple, int[] capacity) {
        int sum = 0;
        for(int num:apple){
            sum+=num;
        }
        
        Arrays.sort(capacity);
        for(int i = capacity.length-1;i>=0;--i){
           
                sum-=capacity[i];
            if(sum<=0){
                return  capacity.length-1-i+1;
            }
        }
        return capacity.length;
    }
}

Problem B

Maximize Happiness of Selected Children

思路

贪心 最优解为从大到小选人 开暴

代码

class Solution {
    public long maximumHappinessSum(int[] happiness, int k) {
        Arrays.sort(happiness);
        int n = happiness.length;
        long sum = 0;
        int cnt = 0;
        int i = n-1;
        while(cnt<k){
            sum = (sum+Math.max(0,happiness[i--]-cnt));
            cnt++;
            
        }
        return sum;
    }
}

Problem C

Shortest Uncommon Substring in an Array

思路

数据结构题 按照题意直接开暴就完事了

代码

class Solution {
    public String[] shortestSubstrings(String[] arr) {
        int n = arr.length;
        Map<String,Integer> map = new HashMap<>();
        List<Map<String,Integer>> l = new ArrayList<>();
        for(int i = 0;i<n;++i){
            l.add(new HashMap<String,Integer>());
            int m = arr[i].length();
            for(int j = 0;j<m;++j){
                StringBuilder sb = new StringBuilder("");
                for(int k = j;k<m;++k){
                    sb.append(arr[i].charAt(k));
                    String s = sb.toString();
                    l.get(i).put(s,l.get(i).getOrDefault(s,0)+1);
                    map.put(s,map.getOrDefault(s,0)+1);
                }
            }
            
        }
        String[] ans = new String[n];
        for(int i = 0;i<n;++i){
            String s = arr[i];
            if(map.get(s)>1){
                ans[i] = "";
                continue;
            }
            ans[i] = s;
            for(String t:l.get(i).keySet()){
                int cnt = map.get(t);
                int cnt2 = l.get(i).get(t);
                if(cnt==cnt2){
                    if(t.length()<ans[i].length()||(t.length()==ans[i].length()&&t.compareTo(ans[i])<0)){
                        ans[i] = t;
                    }
                }
               
            }
        }
        return ans;
    }
}
        

Problem D

Maximum Strength of K Disjoint Subarrays

思路

动态规划
考虑定义dp数组dp[j][i] 表示前i个元素划分为j段的最大值
接下来考虑转移过程
因为不需要全覆盖,因此转移有两种情况

  • 不选当前元素 dp[j][i] = dp[j][i-1]
  • 选当前元素,则最终结果应该表示为如下的格式
    $$ dp[j][i] = \max{dp[j-1][k]+weight(nums[k+1:i])} $$
    其中weight函数是计算题目中所说的权重

不难发现 因为转移状况中的需要枚举k,所以目前的时间复杂度为$o(n^3)$ 明显不符合题目的要求 因此考虑对转移方程进行优化

原有的weight函数可以表示为如下所示
$$(-1)^{i+1}sum[i](x-i+1)$$
其中使用前缀和优化可得
$$sum[i] = pre[i]-pre[k]$$
带入可得
$$(-1)^{i+1}sum[i]
(x-i+1) = (-1)^{i+1}(pre[i]-pre[k])(x-i+1)$$
$$ = (-1)^{i+1}(pre[i]-pre[k])
(x-i+1)$$
其中$ (-1)^{i+1}(x-i+1) $ 和 $pre[i] $ 与枚举的k无关 可以直接将转移情况2中的方程改写为如下形式
$$ dp[j][i] = \max_{k=j}^{i-1} { {dp[j-1][k]-w
pre[k]} }+wpre[i] $$
现在考虑固定j 在求解dp[j][i]和dp[j][i-1]时 求最大值枚举的k分别为
i = i-1,i-2,....,j
i-1 = i-2,....,j-1
可以发现在枚举过程中,新增的枚举项只有i-1的情况,其他在直接已经计算过,因此可以考虑从小到大遍历i 维护一个变量保存最大值,每次使用w
pre[j-1]更新最大值即可
由此,我们可以在O(1)时间内获取到第二种情况的转移结果。

接下来 考虑初始化的问题,因为不能为空 所以要将dp[j][j-1]设置为无穷小 因为j-1个数不能分为j段

转移顺序也不难得出 需要j从小到大 i也从小到大

最终结果应该为dp[k][n]

注意下面的代码中i,j是互换的

代码

补题代码

class Solution {
    public long maximumStrength(int[] nums, int k) {
        int n = nums.length;
        long[][] dp = new long[k+1][n+1];
        long[] pre = new long[n+1];
        for(int i = 0;i<n;++i){
            pre[i+1] = nums[i]+pre[i];
        }
        for(int i = 1;i<=k;++i){
            dp[i][i-1] = Long.MIN_VALUE;
            long mx = Long.MIN_VALUE;
            long w = i%2==0?-1:1;
            w = w*(k-i+1);
            for(int j = i;j<=n;++j){
                mx = Math.max(mx,dp[i-1][j-1]-pre[j-1]*w);
                dp[i][j] = Math.max(dp[i][j-1],mx+w*pre[j]);
            }
        }
        return dp[k][n];
    }
}

总结

本场简单 成功AK 但是第四题的思路不清晰 补学了下树状数组

标签:pre,Contest,int,sum,long,length,388,dp,Weekly
From: https://www.cnblogs.com/baihualiaoluan/p/18078748

相关文章

  • Monoxer Programming Contest 2024(AtCoder Beginner Contest 345)
    MonoxerProgrammingContest2024(AtCoderBeginnerContest345)\(A\)Leftrightarrow\(100pts\)按照题意模拟即可。点击查看代码intmain(){strings;inta=0,b=0,c=0,i;cin>>s;for(i=0;i<s.size();i++){a+=(s[i]=='<&#......
  • AtCoder Beginner Contest 345
    是这样的,C的longlong只开了ans没开全局,AC12WA12,调了一个小时,在赛后1min发现了该错误。没开longlong见祖宗,望周知;这是C的码,简单的小题一只,可怜的longlong。#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;strings;intn,f,ans;map<char......
  • AtCoder Grand Contest 022 E Median Replace
    洛谷传送门AtCoder传送门考虑对于一个确定的串怎么判断合法性。容易发现删到某个时刻若\(1\)的个数大于\(0\)的个数了,因为我们肯定不会蠢到在不是全\(1\)的时候删\(111\),所以\(c_1-c_0\)在不是全\(1\)的时候至少是不会变小的。所以我们的目标就是让\(c_1-c_0......
  • Dwango Programming Contest 6th D 题解
    正好测试一下专栏的题解系统。我省选寄了都怪洛谷/fn/fn/fn/fn/fn/fn/fn题解显然可以对于所有关系建有向边,显然是基环外向树森林。由于是字典序最小,因此找到最小的上一个点没有直接连向边的点一定最优。但是有时取最优会导致最后无法选完,我们考虑无法选完的情况。第一种是......
  • AtCoder Beginner Contest 344 A-G 题解
    AtCoderBeginnerContest344A-SpoilerQuestion删除两个|之间的字符Solution按照题意模拟即可Code#include<bits/stdc++.h>usingnamespacestd;intmain(){strings;cin>>s;stringp1,p2;for(inti=0;i<s.size();i++){......
  • Toyota Programming Contest 2024#3(AtCoder Beginner Contest 344)
    C先预处理出三个数组能拼出的数,存放到map中。查询的时候只需要看这个数是否出现在map里即可。时间复杂度\(O(n^3\logv+Q\logv)\),\(n\leq100\),\(\logv\)是map的时间复杂度。#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=3e......
  • AtCoder Beginner Contest 344
    B-Delimiter难度:⭐题目大意把一个数组倒序输出;解题思路没啥好说的;神秘代码#include<bits/stdc++.h>#defineintlonglong#defineIOSios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#defineendl'\n'usingnamespacestd;constintN=4e6+......
  • AtCoder Beginner Contest 344
    A-Spoiler#include<bits/stdc++.h>usingnamespacestd;usingi32=int32_t;usingi64=int64_t;usingldb=longdouble;#defineinti64usingvi=vector<int>;usingpii=pair<int,int>;constintmod=998244353;constintinf......
  • AtCoder Beginner Contest 344
    AtCoderBeginnerContest344ABCD略EInsertorErase手写链表调了这么久。。链表模板。FEarntoAdvance考虑DP,但是我们发现不是很好转移,然后我们发现\(n\le80\),我们观察一下题目的性质。如果路径确定了,那么我们肯定会在最大值的地方使劲加到终点为止。那么我们考......
  • AtCoder Beginner Contest 344
    基本情况ABCE秒了,D小细节处理出错(太久没写dp)+4。D-StringBagshttps://atcoder.jp/contests/abc344/tasks/abc344_d分组背包,但是字符串的细节要注意signedmain(){intn;std::stringT,str[110][15];intF[110][110],a[110];std::cin>>T>>n;......