题目:click
树木规划
如果第一棵树以及第二棵树都需要移动,优先选择移动第二棵树。直接从第一棵树贪。
class Solution {
public:
int treePlanning(vector<int> &trees, int d) {
int ans=0;
for(int i=0;i<trees.size();++i) {
int j=i+1;
while(trees[i]+d>trees[j]&&j<trees.size()) {
ans++;
j++;
}
i=j-1;
}
return ans;
}
};
正三角形拼接
记录每根木棍长度的个数,数量大于2的直接0,等于2的检查是否有2*len以及是否是最后一个满足则为1,其余2。
class Solution {
public:
int makeEquilateralTriangle(vector<int> &lengths) {
sort(lengths.begin(),lengths.end());
map<int,int>hh;
for(int i=0;i<lengths.size();++i) {
hh[lengths[i]]++;
if(hh[lengths[i]]>=3) {
return 0;
}
}
lengths.erase(unique(lengths.begin(),lengths.end()),lengths.end());
for(int i=0;i<lengths.size();++i) {
if(hh[lengths[i]*2]) {
return 1;
}
if(hh[lengths[i]]>=2&&lengths.size()-1!=i) {
return 1;
}
}
return 2;
}
};
大楼间穿梭
3种状态,直接dp,需要找到位置i后第一个大于等于位置高度的点(栈或双向队列维护出来)。
奇怪的是题目上写的是高于位置的楼房。
typedef long long ll;
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
ll dp[100100];
int suf[100010];
int a[100010];
stack<int>hh;
class Solution {
public:
long long shuttleInBuildings(vector<int> &heights, int k, int x, int y) {
int n=heights.size();
for(int i=0;i<=n+4;++i) {
dp[i]=llinf;
suf[i]=n+1;
}
for(int i=0;i<heights.size();++i) {
a[i+1]=heights[i];
}
for(int i=1;i<=n;++i) {
while(hh.size()&&a[i]>=a[hh.top()]) {
suf[hh.top()]=i;
hh.pop();
}
hh.push(i);
}
dp[1]=0;
for(int i=1;i<=n;++i) {
dp[i+1]=min(dp[i+1],dp[i]+y);
dp[i+2]=min(dp[i+2],dp[i]+y);
if(suf[i]!=n+1&&suf[i]-i<=k) {
dp[suf[i]]=min(dp[suf[i]],dp[i]+x);
}
}
while(hh.size())
hh.pop();
return dp[n];
}
};
对称前后缀
dp找出子串的回文最长长度。如果dp[i][j]为回文串长度等于区间长度,那么贡献值则是整个区间的长度(完全对称),否非除以2.
long long dp[3010][3010];
char hh[3010];
class Solution {
public:
long long suffixQuery(string &s) {
memset(dp,0,sizeof(dp));
long long ans=0;
int n=s.size();
for(int i=0;i<n;++i) {
hh[i+1]=s[i];
}
for(int i=1;i<=n;++i) {
dp[i][i]=1;
}
for(int i=n;i>0;--i) {
for(int j=i+1;j<=n;++j) {
if(i==j-1) {
if(hh[i]==hh[j])
dp[i][j]=2;
else
dp[i][j]=0;
}
else {
if(hh[i]==hh[j]) {
dp[i][j]=max(dp[i][j],dp[i+1][j-1]+2);
}
}
}
}
for(int i=1;i<=n;++i) {
for(int j=i+1;j<=n;++j) {
if(dp[i][j]==(j-i+1))
ans+=(j-i+1);
else
ans+=dp[i][j]/2;
}
}
return ans+n;
}
};