期望 100+30+10
实际 100+30+10
T1字符串模拟,直接开不知为何特别讨厌这道题,20分钟写了近80行才水过
T2很容易根据lca思想想到直接去遍历树,并看每一条路径中恶少边的数量与国有边的差值,如果小于0,提出来放到一个集合里处理,but这知识蒟蒻考场上的30分做法,正解用的是deque(其实更好的利用了dfs的性质)可以遍历树的时候直接动态处理点
Code(包含30分的ugly部分分)
#include<bits/stdc++.h>
#define re register
#define ll long long
#define inl inline
using namespace std;
int read(){
int sum=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
while(isdigit(c)){sum=(sum<<3)+(sum<<1)+(c^48);c=getchar();}
return sum*f;
}
const int N=2e5+10;
int cnt,head[N],n,E;
ll ans;
struct node{
int nxt,to,from,num;
bool s;
}e[N<<1];
inl void add(int u,int v,bool k,int num){
e[++cnt].from=u;
e[cnt].to=v;
e[cnt].nxt=head[u];
e[cnt].num=num;
e[cnt].s=(k==1?1:0);
head[u]=cnt;
}
bool vis[N];
int sum[N],cn[N<<1],tmp,kk[N];
deque<int> q;
inl void dfs(int u,int fa,int dis){
while(!q.empty()&&q.size()>dis/2){
q.pop_front();
ans+=E;
}
vis[u]=1;
//cout<<u<<" "<<cnt1<<" "<<cnt2<<endl;
for(re int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(vis[v]) continue;
if(!e[i].s) q.push_back(v);
dfs(v,u,dis+1);
if(!e[i].s&&!q.empty()&&q.back()==v) q.pop_back();
}
}
int main(){
//freopen("protect.in","r",stdin);freopen("protect.out","w",stdout);
n=read(),E=read();
for(re int i=1;i<n;i++){
int u=read(),v=read();string s;
cin>>s;
bool k=0;
if(s[0]=='p') k=1;
add(u,v,k,i),add(v,u,k,i);
}
dfs(1,0,0);
/*tmp=0;memset(cn,0,sizeof(cn));
for(re int i=1;i<=n;i++){if(sum[i]<0) cn[++tmp]=i,kk[tmp]=sum[i];}
//for(re int i=1;i<=tmp;i++) cout<<kk[i]<<endl;
for(re int i=1;i<=tmp;i++){
//cout<<kk[i]<<endl;
while(kk[i]<0){
while(!q[cn[i]].empty()){
kk[i]+=2;
ans+=E;
for(re int j=i+1;j<=tmp;j++){
if(q[cn[j]].front()==q[cn[i]].front()){
q[cn[j]].pop();kk[j]+=2;
}
}
q[cn[i]].pop();
if(kk[i]>=0) goto lzb;
}
}
lzb:;
}*/
printf("%lld\n",ans);
return 0;
}
T3只剩十分钟了,直接固输了((
其实动态规划方程还挺好推的,dp[t][i][j][k][y]
Code(学自wyf学姐😍)
#include<bits/stdc++.h>
#define re register
#define int long long
#define inl inline
using namespace std;
int read(){
int sum=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
while(isdigit(c)){sum=(sum<<3)+(sum<<1)+(c^48);c=getchar();}
return sum*f;
}
const int N=35;
int dp[61][6][6][6][6],b[10],n,l;
struct node{
int s,d;
}e[N<<2];
const int maxn=1e18;
bool cmp(node a,node b){
return a.s<b.s;
}
signed main(){
//freopen("traffic.in","r",stdin);freopen("traffic.out","w",stdout);
n=read(),l=read();
for(re int i;i<=n;i++){
char ch;cin>>ch>>e[i].s;
if(ch=='N') e[i].d=1;
if(ch=='S') e[i].d=2;
if(ch=='W') e[i].d=3;
if(ch=='E') e[i].d=4;
}
sort(e+1,e+1+n,cmp);
for(re int t=0;t<=60;t++){
for(re int i=0;i<=l;i++)
for(re int j=0;j<=l;j++){
for(re int k=0;k<=l;k++){
for(re int y=0;y<=l;y++) dp[t][i][j][k][y]=maxn;
}
}
}
int now=1;
dp[0][0][0][0][0]=0;
for(re int t=1;t<=60;t++){
b[1]=b[2]=b[3]=b[4]=0;
while(e[now].s==t) b[e[now].d]++,now++;
for(re int i=0;i<=l;i++){
for(re int j=0;j<=l;j++){
for(re int k=0;k<=l;k++){
for(re int y=0;y<=l;y++){
if(dp[t-1][i][j][k][y]==maxn) continue;
int c[5];
c[1]=i+b[1],c[2]=j+b[2],c[3]=k+b[3],c[4]=y+b[4];
if(!(c[1]-1>l||c[2]-1>l||c[3]>l||c[4]>l)){
dp[t][max(c[1]-1,0ll)][max(c[2]-1,0ll)][c[3]][c[4]]=min(dp[t][max(c[1]-1,0ll)][max(c[2]-1,0ll)][c[3]][c[4]],dp[t-1][i][j][k][y]+max(c[1]-1,0ll)+max(c[2]-1,0ll)+c[3]+c[4]);
}
if(!(c[1]>l||c[2]>l||c[3]-1>l||c[4]-1>l)){
dp[t][c[1]][c[2]][max(c[3]-1,0ll)][max(c[4]-1,0ll)]=min(dp[t][c[1]][c[2]][max(c[3]-1,0ll)][max(c[4]-1,0ll)],dp[t-1][i][j][k][y]+max(c[3]-1,0ll)+max(c[4]-1,0ll)+c[1]+c[2]);
}
}
}
}
}
}
int minn=maxn;
for(re int i=0;i<=l;i++){
for(re int j=0;j<=l;j++){
for(re int k=0;k<=l;k++){
for(re int y=0;y<=l;y++){
minn=min(minn,dp[60][i][j][k][y]);
}
}
}
}
if(minn==maxn)puts("No solution");
else printf("%lld",minn);
return 0;
}
写在最后:这次没挂分,但是不理想,csp与noip马上就要来了,感觉这两个月的水平已经有了质的飞跃(奆佬勿喷),但是还有很大的提升空间,最近得更加抓紧时间,多做题多总结,不辜负自己,总之就像今天的T2,明明可以做到更好,但为什么不呢?ybt方面最近也是加紧收尾工作,虽然最近因为没啥味的文化课新章三天才能出来一章😢,冲吧,Pick up my weapon and face it,there's blood on the crown go and take it