D-造桥_牛客小白月赛47 (nowcoder.com)
化成树的问题去做记忆化搜索才过了百分之7的数据,,,正解是求出以每个字母结尾的串的最大长度,然后从a到z枚举一边就行,dp的思想,有点难想
代码查看 (nowcoder.com)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(i) ((-i)&(i))
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
ll t,n,f[30];
char s[200005];
int main(){
//freopen("in.txt","r",stdin);
scanf("%lld",&t);
while(t--){
memset(f,0,sizeof(f));
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%s",s+1);
ll len=strlen(s+1);
int l=s[1]-'a';
int r=s[len]-'a';
f[r]=max(f[r],f[l]+len);
}
ll ans=0;
for(int i=0;i<=25;i++)
ans=max(ans,f[i]);
printf("%lld\n",ans);
}
return 0;
}
三回文序列 - 题目 - Daimayuan Online Judge 4/10
思路就是枚举1-26个字符,让其做a(因为回文是aba形式的),然后统计两边a的个数,再去枚举1-26个字符去找b,选择最大的,其实这个思路想到了,但不会打,最后看了大佬的代码,感觉挺妙的;
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(i) ((-i)&(i))
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
ll t,n,a[200005],b[30],tx[30];
ll ask(ll u){
ll l=1,r=n,res=tx[u],cnt=0;
while(l<r){
while(l<r&&a[l]!=u){
tx[a[l]]--;//不是u就--
l++;
}
while(r>l&&a[r]!=u){
tx[a[r]]--;//不是u就--
r--;
}
cnt+=min(2LL,tx[u]);//最大的情况就是两边都是u,累加cnt是为了计算更中间的情况
l++,r--;
tx[u]-=2;//如果l和r都是u的话,就是要都减去2
//如果不是的话,也就说明结束了,也不会对答案造成影响
for(int i=1;i<=26;i++) res=max(res,cnt+tx[i]);
}
return res;
}
int main(){
//freopen("in.txt","r",stdin);
scanf("%lld",&t);
while(t--){
for(int i=1;i<=26;i++) tx[i]=b[i]=0;
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
tx[a[i]]++;
}
for(int i=1;i<=26;i++){
b[i]=tx[i];
}
ll ans=0;
for(int i=1;i<=26;i++){
if(tx[i]) ans=max(ans,ask(i));
for(int j=1;j<=26;j++) tx[j]=b[j];
}
printf("%lld\n",ans);
}
return 0;
}
Problem - C - Codeforces 4/10
想复杂了,其实可以把相同父节点的数字看成是1组,然后要想尽可能快的感染全部的话自然是要先从数量多的那组开始,然后第i组(假设第i组在第i秒开始有被感染的)全被感染的时间就是数量+i-1
;如果全部的组都有传染这了,那么我们就可以继续执行这样的操作,还是对花时间多的先进行操作,每次操作可以让花费的时间减1,最后只要花的时间大于等于花时间最多的一组的时间了就停止;
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(i) ((-i)&(i))
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
ll t,n,a[200005],x;
int main(){
//freopen("in.txt","r",stdin);
scanf("%lld",&t);
while(t--){
scanf("%lld",&n);
for(int i=2;i<=n;i++){
scanf("%lld",&x);
a[x]++;
}
sort(a+1,a+n+1,greater<ll>());
ll ans=1;//要算上1节点
priority_queue<ll>q;
for(int i=1;i<=n;i++){
if(a[i]){
ans++;
q.push(a[i]+i-1);
a[i]=0;
}
else break;
}
while(ans<q.top()){
ans++;
ll x=q.top()-1;
q.pop();
q.push(x);
}
printf("%lld\n",ans);
}
return 0;
}