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];
}
};