力扣 第488场周赛(A~D)

A:3833. 统计主导元素下标数

算一下sum,然后一边遍历一边减即可判断当前元素是否是主导元素。

 1 class Solution {
 2 public:
 3     int dominantIndices(vector<int>& nums) {
 4         int sum=accumulate(nums.begin(),nums.end(),0);
 5         int ans=0,n=nums.size();
 6         for(int i=0;i<n-1;i++){
 7             sum-=nums[i];
 8             if(nums[i]>float(sum)/(n-i-1))
 9                 ans++;
10         }
11         return ans;
12     }
13 };

B:3834. 合并相邻且相等的元素
要求合并最左侧相邻相等的元素,合并之后放回原位置,可再次合并。分析后,操作完美符合栈。

 1 class Solution {
 2 public:
 3     vector<long long> mergeAdjacent(vector<int>& nums) {
 4         vector<long long> S;
 5         for(int i=0;i<nums.size();i++){
 6             S.push_back(nums[i]);
 7             while(S.size()>=2){
 8                 int t=S.size();
 9                 if(S[t-1]!=S[t-2]) break;
10                 long long a=S[t-1];
11                 S.pop_back();
12                 S.pop_back();
13                 S.push_back(a*2);
14             }
15         }
16         return S;
17     }
18 };

C:3835. 开销小于等于 K 的子数组数目
定义一个数组的cost为(max-min)*len,用单调队列维护min,max。

 1 class Solution {
 2 public:
 3     long long countSubarrays(vector<int>& nums, long long k) {
 4         long long n=nums.size();
 5         long long ans=0;
 6         deque<long long> qmin,qmax;
 7         long long l=0,r;
 8         auto getcost=[&](){
 9             return (nums[qmax.front()]-nums[qmin.front()])*(r-l+1);
10         };
11         for(r=0;r<n;r++){
12             while(!qmin.empty() && nums[qmin.back()]>=nums[r]) qmin.pop_back();
13             qmin.push_back(r);
14             while(!qmax.empty() && nums[qmax.back()]<=nums[r]) qmax.pop_back();
15             qmax.push_back(r);
16             while(getcost()>k){
17                 if(qmin.front()==l)
18                     qmin.pop_front();
19                 if(qmax.front()==l)
20                     qmax.pop_front();
21                 l++;
22             }
23             ans+=r-l+1;
24         }
25         return ans;
26     }
27 };

D:3836. 恰好 K 个下标对的最大得分

给定两个数组,从数组a和数组b中分别选k个元素,得分为这两个k维向量的点积,问最大得分为多少?

定义f(i,j,k)为从a中前i个和b中前j个分别选k个元素的最大得分。

则有初始化k==0---->f=0

    i<k || j<k ------->f=-INF

由于存在负数元素,且求最大值,那么除了上面为0的元素,其他的都可初始化为-INF。

转移方程,考虑a选不选第i个和b选不选第j个。

f(i,j,k)=max(f(i-1,j,k),f(i,j-1,k),f(i-1,j-1,k-1)+ai*bi)

 1 const int N = 110;
 2 typedef long long LL;
 3 LL f[N][N][N];
 4 class Solution {
 5 public:
 6     long long maxScore(vector<int>& nums1, vector<int>& nums2, int x) {
 7         const LL INF=1ll<<60;
 8         for(int i=0;i<N;i++){
 9             for(int j=0;j<N;j++){
10                 for(int k=0;k<N;k++){
11                     f[i][j][k]=-INF;
12                 }
13             }
14         }
15         for(int i=0;i<N;i++){
16             for(int j=0;j<N;j++){
17                 f[i][j][0]=0;
18             }
19         }
20         int n=nums1.size();
21         int m=nums2.size();
22         
23         for(int i=1;i<=n;i++){
24             for(int j=1;j<=m;j++){
25                 for(int k=1;k<=x;k++){
26                     f[i][j][k]=max(f[i][j-1][k],f[i-1][j][k]);
27                     if(f[i-1][j-1][k-1]!=-INF)
28                         f[i][j][k]=max(f[i][j][k],f[i-1][j-1][k-1]+1ll*nums1[i-1]*nums2[j-1]);
29                 }
30             }
31         }
32         return f[n][m][x];
33     }
34 };

 

posted on 2026-02-15 09:55  greenofyu  阅读(3)  评论(0)    收藏  举报