Rank: 1512 / 3754 AC 2/4
题目传送
非递增顺序的最小子序列
其实并非是DP,而是简单的签到题
class Solution {
public:
vector<int> minSubsequence(vector<int>& nums) {
int sum = 0,n= nums.size(),cur=0;
for(int i=0;i<n;i++){
sum += nums[i];
}
sort(nums.begin(),nums.end(),greater<int>());
vector<int> res;
for(int i=0;i<n;i++){
cur += nums[i];
res.push_back(nums[i]);
if(cur>sum-cur) {
break;
}
}
return res;
}
};
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn) 空间复杂度: O ( n ) O(n) O(n)
将二进制表示减到 1 的步骤数
然而这个题目的数据范围1 <= s.length <= 500
,如果用将二进制字符串换为int/long long的话,都会爆,则只需要模拟一下转换过程即可,先将字符串翻转,如果字符串以1
开头的话,便为奇数,则将距离1
最近的0
之间所有1
变为0
,然后将距离1
最近的0
变为1
,其实就模拟加1的过程;如果字符串以0
开头的话,则直接将字符串第一位去掉即可…
重复这个过程,直到字符串长度为1,字符串为'1'
class Solution {
public:
int numSteps(string s) {
reverse(s.begin(),s.end());
int res = 0;
while(!(s.length()==1&&s[0]=='1')){
res ++;
if(s[0]=='1'){
int j = 0;
while(j<s.length()&&s[j]=='1'){
s[j]='0';
j++;
}
if(s[j]=='0') s[j]='1';
else s+='1';
}
else if(s[0]=='0'){
s = s.substr(1);
}
}
return res;
}
};
时间复杂度: O ( n ) O(n) O(n),空间复杂度: O ( 1 ) O(1) O(1)
最长快乐字符串
参考周赛Rank1写法
ban
表示禁用的,sel
表示要选择的。
class Solution {
public:
string longestDiverseString(int a, int b, int c) {
string res = "";
vector<int> cnt;
cnt.push_back(a); cnt.push_back(b); cnt.push_back(c);
while(true){
int ban = -1;
if(res.size()>=2&&res[res.size()-1]==res[res.size()-2]){
ban = res[res.size()-1]-'a';
}
int sel = -1;
for(int i=0;i<3;i++){
if(ban==i||cnt[i]==0) continue;
else if(sel==-1||cnt[i]>cnt[sel]) sel = i;
}
if(sel==-1) break;
res += 'a'+sel;
cnt[sel]--;
}
return res;
}
};
时间复杂度: O ( a + b + c ) O(a+b+c) O(a+b+c),空间复杂度: O ( a + b + c ) O(a+b+c) O(a+b+c)
石子游戏 III
博弈问题
思路参考:零和!对手采取最优得分最少时,自己最高!
dp[i]表示先手者从第i堆到最后一堆能取到的最大值
尽可能把dp数组开大,这样就不用考虑下标越界的问题
d
p
[
i
]
=
m
a
x
(
d
p
[
i
]
,
s
u
m
−
d
p
[
i
+
1
]
,
s
u
m
−
d
p
[
i
+
2
]
,
s
u
m
−
d
p
[
i
+
3
]
)
dp[i] = max(dp[i],sum-dp[i+1],sum-dp[i+2],sum-dp[i+3])
dp[i]=max(dp[i],sum−dp[i+1],sum−dp[i+2],sum−dp[i+3])
s
u
m
=
∑
i
n
s
t
o
n
e
V
a
l
u
e
[
i
]
sum = \sum _i ^n stoneValue[i]
sum=∑instoneValue[i]
class Solution {
public:
string stoneGameIII(vector<int>& stoneValue) {
int n = stoneValue.size(),sum=0,dp[50010];
memset(dp,0,size(dp));
for(int i=n-1;i>=0;i--){
sum += stoneValue[i];
dp[i] = -10000000;
for(int j=1;j<=3;j++){
dp[i] = max(dp[i],sum-dp[i+j]);
}
}
if(dp[0]>sum-dp[0]) return "Alice";
else if(dp[0]==sum-dp[0]) return "Tie";
else return "Bob";
}
};