leetcode 第191場周賽

數組中兩元素的最大乘積 切割後面積最大的蛋糕 重新規劃路線 兩個盒子中球的顏色數相同的概率
3分 簡單 4分 中等 5分 中等 7分 困難

1464 數組中兩元素的最大乘積

解題思路:

其實就是題目就是要求數組中兩個最大的值

維護最大值first_mx,第二大值second_mx

遍歷數組更新這兩值即可

複雜度:

相當於遍歷了一遍nums數組,故爲O(n)

class Solution {
public:
    int maxProduct(vector<int>& nums) {
        int first_mx=nums[0];
        int second_mx=nums[1];
        if(first_mx<second_mx) swap(first_mx,second_mx);
        for(int i=2;i<nums.size();i++){
            if(nums[i]>first_mx){
                second_mx=first_mx;
                first_mx=nums[i];
            }
            else{
                if(nums[i]>second_mx) second_mx=nums[i];
            }
        }
        return (first_mx-1)*(second_mx-1);
    }
};

1465 切割後面積最大的蛋糕

解題思路:

先將horizontalCuts,和verticalCuts從小到達排一下

兩個相鄰水平切口的距離就是矩形的高

兩個相鄰豎直切口的距離就是矩形的寬

維護高寬的最大值即可

複雜度:

遍歷都是O(n),最高是從小到大sort的複雜度,最後的複雜度是爲O(nlogn)

const long long mod=1e9+7;
class Solution {
public:
    int maxArea(int h, int w, vector<int>& horizontalCuts, vector<int>& verticalCuts) {
        int len_h=horizontalCuts.size();
        int len_v=verticalCuts.size();
        sort(horizontalCuts.begin(),horizontalCuts.end());
        sort(verticalCuts.begin(),verticalCuts.end());
        int a=max(h-horizontalCuts[len_h-1],horizontalCuts[0]),b=max(w-verticalCuts[len_v-1],verticalCuts[0]);
        for(int i=1;i<horizontalCuts.size();i++){
            a=max(a,horizontalCuts[i]-horizontalCuts[i-1]);
        }
        for(int i=1;i<verticalCuts.size();i++){
            b=max(b,verticalCuts[i]-verticalCuts[i-1]);
        }
        long long ans=(long long)a*b%mod;
        return ans;
    }
};

 


1466 重新規劃路線

解題思路:

map記錄有向邊,建圖建的是無向圖,從1出發,向兒子節點出發,如果從當前節點到兒子節點的邊是原來的有向邊,說明這邊需要改方向,ans++(ans是最終需要更改的邊的個數)

class Solution {
public:
    int ans=0;
    vector<int>son[50005];
    map<pair<int,int>,int>mp;
    void dfs(int u,int fa){
        for(auto v:son[u]){
            if(v==fa) continue;
            if(mp[make_pair(u,v)]) ans++;
            dfs(v,u);
        }
    }
    int minReorder(int n, vector<vector<int>>& connections) {
        ans=0;
        for(auto it:connections){
            mp[make_pair(it[0]+1,it[1]+1)]=1;
            son[it[0]+1].push_back(it[1]+1);
            son[it[1]+1].push_back(it[0]+1);
        }
        dfs(1,0);
        return ans;
    }
};

 


1467 兩個盒子中球的顏色數相同的概率

解題思路:

簡單dp(爲方便處理,房屋、顏色編號都從1開始,可能需要轉化一下)

dp狀態表示放完前i種顏色的球之後,第一個盒子有j個球,共x種顏色,第二個盒子有j個球,共y種顏色 的方案數
dp[i][j][k][x][y]
​
1)對於第i種球,全加給第一個盒子,或這全加給第二個盒子
dp[i][j][k][x][y]+=dp[i-1][j-t][k][x-1][y]*C[j][t];
全加給某個盒子,該盒子顏色加1,另一個顏色數不變,該盒子個數加上t
    
2)對於第i種求,部分加給第一個盒子,部分加給第二個盒子
for(int b=1;b<t;b++) 枚舉加給第一個盒子b個,那麼加給第二個盒子t-b個,此時第一個盒子顏色x加了1,第二個盒子顏色y加了1
dp[i][j][k][x][y]+=dp[i-1][j-b][k-(t-b)][x-1][y-1]*C[j][b]*C[k][t-b];
​
本題還涉及到排列的問題,在狀態轉移過程種還需要加上組合數
例如情況1,把t個球加給盒子1,盒子一現在有j個球,那麼這樣的排列有C[j][t]種
也就是說,如果要向一個已經有a個球的盒子裏放入b個數,那麼方案數要乘上 C[a+b][b];

複雜度:

O(n^2 * k^3 * max(ni))

 

class Solution {
    long double dp[9][25][25][9][9];
    long double C[25][25];
public:
    double getProbability(vector<int>& balls) {
​
        dp[0][0][0][0][0]=1;
        int n=balls.size();
        int sum=0;
        for(auto it:balls) sum+=it;
        sum/=2;
​
        //C[][]組合數
        C[0][0]=1;
        for (int i=1;i<=sum;++i){
            C[i][0]=1;
            for(int j=1;j<=i;++j)
                C[i][j]=C[i-1][j]+C[i-1][j-1];
        }
​
        for(int i=1;i<=n;i++){
            int t=balls[i-1];
            for(int j=sum;j>=t;j--){
                for(int k=0;k<=sum;k++){
                    for(int x=1;x<=i;x++){
                        for(int y=0;y<=i;y++){
                            dp[i][j][k][x][y]+=dp[i-1][j-t][k][x-1][y]*C[j][t];
                            dp[i][k][j][y][x]+=dp[i-1][k][j-t][y][x-1]*C[j][t];
                        }
                    }
                }
            }
            for(int b=1;b<t;b++){
                for(int j=sum;j>=b;j--){
                    for(int k=sum;k>=t-b;k--){
                        for(int x=1;x<=i;x++){
                            for(int y=1;y<=i;y++){
                                dp[i][j][k][x][y]+=dp[i-1][j-b][k-(t-b)][x-1][y-1]*C[j][b]*C[k][t-b];
                            }
                        }
                    }
                }
            }
        }
        long double ans1=0,ans2=0;
        for(int i=0;i<=n;i++){
            ans1+=dp[n][sum][sum][i][i];
        }
        for(int i=0;i<=n;i++){
            for(int j=0;j<=n;j++){
                ans2+=dp[n][sum][sum][i][j];
            }
        }
        ans1=ans1/ans2;
        return ans1;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章