leetcode 350 场周赛

A简单

class Solution {
public:
    int distanceTraveled(int mainTank, int additionalTank) {
        int res=0;
        while(mainTank){
            mainTank--;
            res+=10;
            if(res%50==0 && additionalTank){
                mainTank++;
                additionalTank--;
            }
            
        }
        return res;
    }
};

B 说白了就是找一个最小距离

class Solution {
public:
    int findValueOfPartition(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int res=1e9;
        for(int i=1;i<nums.size();i++){
            res=min(res,nums[i]-nums[i-1]);
        }
        return res;
    }
};

C

首先最开始想 是一个dfs 暴力搜索一下 但是 最大N=14 O(14!)这么大 所以这样暴力搜索就不行了 考虑下 如果 记忆化搜索 那么用数位DP,时间复杂度为2^N *N 每次再遍历一遍 所以总的时间复杂度为2^N * N * N 每次会重复 会多搜 所以 用数组 f[1<<n][n]来存储
class Solution {
public:
    int specialPerm(vector<int>& nums) {
        int n=nums.size(),mod=1e9+7;
        int ans=0,f[1<<n][n];
        memset(f,0,sizeof f);
        function<int(int,int)> dfs=[&](int left,int i){
            if(left==0)return 1;
            int &res=f[left][i];
            if(res) return res;
            for(int j=0;j<n;j++){
                if(left>>j&1&&(nums[j]%nums[i]==0 || nums[i]%nums[j]==0))  res=(dfs(left^(1<<j),j)+res)%mod;
            }
            return res;
        };
        for(int i=0;i<n;i++){
            ans=(dfs(((1<<n)-1)^(1<<i),i)+ans)%mod;
        }
        return ans%mod;
    }
};

D

首先考虑了贪心 但是没证明出来 DP 首先 n=收费的+不收费
收费time[i] (付费时间和)>=n-收费个数(不收费)
time[i]+收费个数 >=n 这里就是 time[i]+1
这里说明 dp(01背包)的时候 选择收费和不收费的取最小值就行 但是需要判断一下当你选择的背包 如果 j 减 选择的时间<0那么说明这里选的体积为0 说明就不能选就选择0
这里体积就是 >=n的最小值
class Solution {
public:
    int paintWalls(vector<int>& cost, vector<int>& time) {
        int n=cost.size();
        int dp[n+1];
        memset(dp,0x3f,sizeof dp);
        dp[0]=0;
        for(int i=0;i<n;i++){
            int c=cost[i],t=time[i]+1;
            for(int j=n;j>0;j--){
                dp[j]=min(dp[j],dp[max(j-t,0)]+c);
            }
        }
        return dp[n];
    }

};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值