LeetCode219周赛

5625.比赛中的配对次数

在这里插入图片描述

n个队伍中选出一个冠军,所以要淘汰n-1个队伍,总共进行n-1次比赛。如果理解了就直接return n-1;

如果一下子没有看出来,则模拟题目即可。如果是偶数,则直接n/2加到总次数中,如果是奇数,也是n/2加到总数中,但是n=(n-1)/2+1,因为有支队伍直接晋级。

class Solution {
public:
    int numberOfMatches(int n) {
        return n-1;
    }
};
class Solution {
public:
    int numberOfMatches(int n) {
        int res=0;
        while(n!=1){
            if(n%2==0)
            {
                res+=n/2;
                n>>=1;
            }
            else
            {
                res+=n/2;
                n=(n-1)/2+1;
            }
        }
        return res;
    }
};

5626.十-二进制数的最少数目

在这里插入图片描述

没有前导0,那么就直观想一下,9999那就9个1111,如果是9998,那就是8个1111再加上1个1110,一共是9个,所以很显然,答案就是数中最大值。这个题很友善,给的是字符串,所以直接遍历找到最大值就可以了。

class Solution {
public:
    int minPartitions(string n) {
		int res=0;
        for(int i=0; i<n.length();i++)
        {
            res=max(res,n[i]);
        }
        return res;
    }
};

5627.石子游戏VII

在这里插入图片描述

这个石子的题目已经有这么多花样了。

这题目很友善,告诉了我们先手的一定能赢,后手的要尽力缩小差值,而先手的要尽力扩大差值,又根据题意,得分是去掉左侧或右侧石子后剩下的总和,而最终要求的是两人总分的差值。

我们设 sum[i][j]为石子从i 到 j的总和;

dp[i][j]是为在i到j区间里先手的总分减去后手的总分,也就是差值。

假设轮到我来选,选择移除最左侧的石子,那么我的得分就是sum[i+1][j],那么此时区间sum[i+1][j]对方的得分是多少呢?我们不知道,但是也不需要知道,因为我们知道dp[i+1][j]是两者的差值。

那么sum[i+1][j]-dp[i+1][j]

= 我当前的得分 - (对方的总分 - 我的总分)

= 我当前的得分 + 我的总分 - 对方的总分

= 我的新的总分 - 对方的总分

那此时,不就恰恰是dp[i][j]嘛。

同理,如果从左侧拿石子则换成[i][j-1] ,轮到对方就把我和对方换一下。

然后我们来推一下状态转移方程。注意,我们要从只有一堆的时候扩展,扩展到0到n-1

1.最开始的时候:i==j ,dp[i][j]=0,因为拿掉之后没得选了

2.当j-i==1时,也就是说只有两堆石子了,那么我肯定要拿掉较小的,获得最大得分,因为拿掉之后,对方再拿就没有分了,所以dp[i][j]=max(stones[i],stones[j]);

3.当j-i>1时,就想刚才上面分析的一样。

dp[i][j]=max(sum[i+1][j]-dp[i+1][j] , sum[i][j-1]-dp[i][j-1]);

最后返回dp[0][n-1]即为所需的答案,表示剩下的石子为0到n-1时,能取得的最大价值差

class Solution {
public:
    int stoneGameVII(vector<int>& stones) {
        int n=stones.size();
        vector<vector<int>> sum(n,vector<int>(n,0));
        for(int i=0;i<n;i++)
        {
            for(int j=i;j<n;j++)
            {
                if(i==j) sum[i][j]=stones[i];
                else sum[i][j]=sum[i][j-1]+stones[j];
            }
        }
        vector<vector<int>> dp(n,vector<int>(n,0));
        for(int i=n-1;i>=0;i--)
        {
            for(int j=i+1;j<n;j++)
            {
                if(j-i==1) dp[i][j]=max(stones[i],stones[j]);
                else dp[i][j]=max(sum[i+1][j]-dp[i+1][j],sum[i][j-1]-dp[i][j-1]);
            }
        }
        return dp[0][n-1];
    }
}

5245.堆叠长方体的最大高度

在这里插入图片描述

因为题目说了长方体可以随意摆放,所以我们可以先排序,也就是说,我们可以让最小的两条边作为底,最大的边做为高,这样就可以找到最高的。

然后我们就依次考虑第1到i-1个长方体,看看是否能够将第i个长方体拼接在它的下方,然后更新当前的最大值。

class Solution {
public:
    int maxHeight(vector<vector<int>>& cuboids) {
        int n=cuboids.size();
        for(auto &s : cuboids)
        {
            sort(s.begin(),s.end());
		}
        sort(cuboids.begin(),cuboids.end());
        vector<int>dp(n);
        int ans=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<i;i++)
            {
                if(cuboids[i][1]<=cuboids[j][1] && cuboids[i][2]<=cuboids[j][2])
                {
                    dp[i]=max(dp[i],dp[j]);
				}
            }
            dp[i]+=cuboids[i][2];
            ans=max(ans,dp[i]);
        }
        return ans;   
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值