C. Cow and Message
题意:
给你一个字符串s,其中间隔为等差数列的子串最多有多少?
思路:
DP
显然该子串只有可能是长度为1或者2的时候子串的数量能尽可能的多。
因为能够成长度为的2以上的子串一定可以先构成长度为2的子串,显然还多了很多限制。
故本题只要计算统计长度为1和2的子串的最大的数量即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 +7;
const ll MAXN = 1e6 + 5;
ll dp[30][30],a[30];
ll res;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
string s;
cin>>s;
for(int i=0;i<s.size();i++){
int t=s[i]-'a';
for(int j=0;j<26;j++){
dp[t][j]+=a[j];//长度为2的
res=max(res,dp[t][j]);
}
a[t]++;//长度为1的子串数量
res=max(res,a[t]);//取长度为1的子串的max
}
cout<<res<<endl;
return 0;
}
D. Cow and Fields
题意:
在所给k个点之间连一条边,求出最大的最短路是多少并输出。
思路:
假设连边的点为x,y;
那么最大的最短路为min(1到x的距离+1+y到n的距离,1到y的距离+1+x到n的距离)
设1到x的距离为ax y到n的距离设为ny 同理…略
即求min(ax+1+ny,ay+1+nx)
当ax+ny<ay+nx的时候取前者,移项可得ax-nx<=ay-ny的时候取前者。
要取的最大的最短路,则应当使ai-ni尽可能的大,可利用sort排序完成。
BFS两次:第一次求出1到任意一点的距离,第二次求出n到任意一点的距离。
排序 遍历求最大值
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 +7;
const ll MAXN = 2e5 + 5;
vector<int>G[MAXN];
int a[MAXN];
int dis1[MAXN],disn[MAXN];
queue<int>q;
bool vis[MAXN];
void bfs(int st,int dis[]){
q.push(st);
memset(vis,0,sizeof(vis));
dis[st]=0;
vis[st]=1;
while(!q.empty()){
int top=q.front();
q.pop();
for(auto v:G[top]){
if(!vis[v]){
dis[v]=dis[top]+1;
q.push(v);
vis[v]=1;
}
}
}
}
vector<pair<int,int> >V;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int n,m,k;
cin>>n>>m>>k;
for(int i=1;i<=k;i++){
cin>>a[i];
}
while(m--){
int x,y;
cin>>x>>y;
G[x].push_back(y);
G[y].push_back(x);
}
bfs(1,dis1);
bfs(n,disn);
int res=0;
for(int i=1;i<=k;i++){
V.push_back({dis1[a[i]]-disn[a[i]],a[i]});
}
sort(V.begin(),V.end());
int ans=0;
int tmp=0;
for(int i=0;i<V.size();i++){
if(i!=0){
ans=max(ans,tmp+disn[V[i].second]+1);
}
tmp=max(tmp,dis1[V[i].second]);
}
cout<<min(ans,dis1[n]);
return 0;
}