ZJOI2006 三色二叉树
Time Limit: 1 Sec Memory Limit: 64 MB
Description
Input
仅有一行,不超过\(500000\)个字符,表示一个二叉树序列。
Output
输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色。
Sample Input
1122002010
Sample Output
5 2
Source
Solution
没有意思的树形DP题,其实不太想做这种一眼题,没有成绩就感,而且看见自己没有一遍过还会很伤心。
显而易见的状态\(dp[i][3]\),后面的的\(3\)分别是\(0,1,2\),分表表示红绿蓝。
其实貌似不用设那么多,直接设一个是不是绿色就可以了,但是已经这样写了就不想改了。
随便转移转移就好了。
#include<cstdio> #include<algorithm> #include<cmath> #include<cstring> using namespace std; #define lowbit(x) ((x)&(-(x))) #define REP(i,a,n) for(register int i=(a);i<=(n);++i) #define PER(i,a,n) for(register int i=(a);i>=(n);--i) #define FEC(i,x) for(register int i=head[x];i;i=g[i].ne) #define dbg(...) fprintf(stderr,__VA_ARGS__) namespace io{ const int SIZE=(1<<21)+1;char ibuf[SIZE],*iS,*iT,obuf[SIZE],*oS=obuf,*oT=oS+SIZE-1,c,qu[55];int f,qr; #define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),(iS==iT?EOF:*iS++)):*iS++) inline void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;} inline int getc(){return gc();} inline void putc(char x){*oS++=x;if(oS==oT)flush();} template<class I>inline void read(I &x){for(f=1,c=gc();c<'0'||c>'9';c=gc())if(c=='-')f=-1;for(x=0;c<='9'&&c>='0';c=gc())x=x*10+(c&15);x*=f;} template<class I>inline void write(I x){if(!x)putc('0');if(x<0)putc('-'),x=-x;while(x)qu[++qr]=x%10+'0',x/=10;while(qr)putc(qu[qr--]);} inline void print(const char *s){while(*s!='\0')putc(*s++);} inline void scan(char *s){for(c=gc();c<=' ';c=gc());for(;c>' ';c=gc())*(s++)=c;*s='\0';} struct Flusher_{~Flusher_(){flush();}}io_flusher_; }//orz laofudasuan using io::read;using io::putc;using io::write;using io::print; typedef long long ll;typedef unsigned long long ull; template<typename A,typename B>inline bool SMAX(A&x,const B&y){return x<y?x=y,1:0;} template<typename A,typename B>inline bool SMIN(A&x,const B&y){return y<x?x=y,1:0;} const int N=500000+7,INF=0x3f3f3f3f; int n,m,dp1[N][3],dp2[N][3],nod,ch[N][3];//错误笔记:ch必须开int型!!! inline int ReadAll(){ int x=++nod;ch[x][0]=io::getc()-'0'; if(ch[x][0]==1)ch[x][1]=ReadAll();else if(ch[x][0]==2)ch[x][1]=ReadAll(),ch[x][2]=ReadAll(); if(!ch[x][0])dp1[x][0]=dp2[x][0]=0,dp1[x][1]=dp2[x][1]=1,dp1[x][2]=dp2[x][2]=0; else if(ch[x][0]==1)dp1[x][0]=max(dp1[ch[x][1]][1],dp1[ch[x][1]][2]),dp1[x][1]=max(dp1[ch[x][1]][0],dp1[ch[x][1]][2])+1,dp1[x][2]=max(dp1[ch[x][1]][0],dp1[ch[x][1]][1]), dp2[x][0]=min(dp2[ch[x][1]][1],dp2[ch[x][1]][2]),dp2[x][1]=min(dp2[ch[x][1]][0],dp2[ch[x][1]][2])+1,dp2[x][2]=min(dp2[ch[x][1]][0],dp2[ch[x][1]][1]); else{ dp1[x][0]=max(dp1[ch[x][1]][1]+dp1[ch[x][2]][2],dp1[ch[x][1]][2]+dp1[ch[x][2]][1]); dp1[x][1]=max(dp1[ch[x][1]][0]+dp1[ch[x][2]][2],dp1[ch[x][1]][2]+dp1[ch[x][2]][0])+1; dp1[x][2]=max(dp1[ch[x][1]][0]+dp1[ch[x][2]][1],dp1[ch[x][1]][1]+dp1[ch[x][2]][0]); dp2[x][0]=min(dp2[ch[x][1]][1]+dp2[ch[x][2]][2],dp2[ch[x][1]][2]+dp2[ch[x][2]][1]); dp2[x][1]=min(dp2[ch[x][1]][0]+dp2[ch[x][2]][2],dp2[ch[x][1]][2]+dp2[ch[x][2]][0])+1; dp2[x][2]=min(dp2[ch[x][1]][0]+dp2[ch[x][2]][1],dp2[ch[x][1]][1]+dp2[ch[x][2]][0]); } return x; } int main(){ #ifndef ONLINE_JUDGE freopen("BZOJ1864.in","r",stdin);freopen("BZOJ1864.out","w",stdout); #endif ReadAll(); write(max(max(dp1[1][0],dp1[1][1]),dp1[1][2])),putc(' '),write(min(min(dp2[1][0],dp2[1][1]),dp2[1][2])),putc('\n'); }
分类:
动态规划 / 动态规划 - 树形DP
, 动态规划
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· 为DeepSeek添加本地知识库
· 精选4款基于.NET开源、功能强大的通讯调试工具
· DeepSeek智能编程
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~