2020-08-15刷题

  1. leetcode-546移除盒子
    题型:动态规划
    难度:困难
    题目:给出一些不同颜色的盒子,盒子的颜色由数字表示,即不同的数字表示不同的颜色。你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止。每一轮你可以移除具有相同颜色的连续 k 个盒子(k >= 1),这样一轮之后你将得到 k*k 个积分。当你将所有盒子都去掉之后,求你能获得的最大积分和。
    代码:
class Solution {
public:
    int dp[100][100][100];
public:
    //不能只考虑连续相同的情况,因为可能会出现:[3,1,3,3,3]这种情况,就要把前面的3和后面三个连起来。
    //本题用动态规划加dfs去做。
    //dfs(left,right,k),表示left~right区间+的连续k个等于right对应元素
    //第一种情况是right-1后面连续k+1个;dfs(left,right-1,0)+(k+1)^2
    //第二种情况是right之前,存在某个位置i,有与其相同的值,可以和后面k+1个进行合并(把right之前的区间,分为两份,前面是包含这个元素+k+1个,后面区间不包含);dfs(left,i,k+1)+dfs(i+1,right-1,0)
    //上面两种情况取最大值dp[left][right][k]?
    int dfs(vector<int> &boxes,int left,int right,int k){
        if(left > right) return 0;
        if(dp[left][right][k] != 0) return dp[left][right][k];
        while(left<right && boxes[right]==boxes[right-1])
        {
            right--;
            k++;
        }
        //if(right>=1)
            dp[left][right][k] = dfs(boxes,left,right-1,0)+(k+1)*(k+1);
        for(int i=left;i<right;i++)
        {
            //看当前这个值,是否和right位置的值相等,相等即第二种情况。
            if(boxes[i] == boxes[right])
            {
                dp[left][right][k] = max(dp[left][right][k],dfs(boxes,left,i,k+1)+dfs(boxes,i+1,right-1,0) );
            }
        }
        return dp[left][right][k];
    }
    int removeBoxes(vector<int>& boxes) {
        memset(dp,0,sizeof(dp));
        int res = dfs(boxes,0,boxes.size()-1,0);
        return res;
    }
};

借鉴:https://leetcode-cn.com/problems/remove-boxes/solution/yi-chu-he-zi-by-leetcode-solution/

  1. leetcode-1007行相等的最少多米诺旋转
    题型:贪心
    难度:中等
    题目:在一排多米诺骨牌中,A[i] 和 B[i] 分别代表第 i 个多米诺骨牌的上半部分和下半部分。(一个多米诺是两个从 1 到 6 的数字同列平铺形成的 —— 该平铺的每一半上都有一个数字。)我们可以旋转第 i 张多米诺,使得 A[i] 和 B[i] 的值交换。返回能使 A 中所有值或者 B 中所有值都相同的最小旋转次数。如果无法做到,返回 -1.
    在这里插入图片描述
    代码:
class Solution {
public:
    //遍历两个数组,如果结果想要满足条件,必须保证最后在同一数组里的这个数值,总个数一定大于等于数组长度。遍历后比长度小,直接返回。满足条件,再遍历一次,选择数组中存在这个数多的,返回缺失的个数,就是最小次数了。
    //注:一个多米诺是两个从 1 到 6 的数字,数值最大为6
    int minDominoRotations(vector<int>& A, vector<int>& B) {
        if(A.size()==0 || A.size()!=B.size()) return -1;
        vector<int> nums(6,0);
        for(int i=0;i<A.size();i++)
        {
            if(A[i] == B[i])
            {
                //如果这张牌两半一样,只能算作一个
                nums[A[i]-1]++;
            }
            else
            {
                nums[A[i]-1]++;
                nums[B[i]-1]++;
            }
        }
        int flag = 0;
        int num = 0;
        for(int i=0;i<6;i++)
        {
            if(nums[i] >= A.size())
            {
                flag = 1;
                num = i+1;
                break;
            }
        }
        if(flag == 0) return -1;
        int count1 = 0;
        int count2 = 0;
        for(int i=0;i<A.size();i++)
        {
            if(A[i] == num) count1++;
            if(B[i] == num) count2++;
        }
        return count1<count2?A.size()-count2:A.size()-count1;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值