APIO2007-2015题解大集合(2008年篇)
2016-04-14 22:43
260 查看
这一系列的题解预计会在未来的一周内陆续出齐。由于作者是现役选手,应该不会弃坑。然而现在由于时间实在太紧张没机会写blog看起来确实要坑了……对不起等后面题解的同学们。。。
首先这题属于计数类DP应该没有异议吧……先把4个字母编号:A=1,C=2,G=3,T=4。
不难写出状态转移方程:f[i,j,k]表示后i位(注意是后i位一会要在前面卡),当前位为j,范式为k的方案数。
f[i][j][k]=∑(f[i+1,l,k或k-1])k或k-1视j与l的关系而定,如果j>l则为k-1,否则为k。对于当前为N的位置要枚举当前位,否则不用枚举,直接就是当前的字母对应的数。
统计出方案数之后,就需要“卡”出答案(这是输出第k大解问题的常见思路)。我们从前到后、从小到大枚举数字(如果不是N就不用枚举了),如果当前r能足够减去f[i,j,k](注意这里的k是在从前往后确定答案的过程中根据前面的情况要变化的),就减去,否则说明当前位就是j,确定当前位,然后接着往后枚举。
最后重要的事情说三遍:要开longlong!要开longlong!要开longlong!CQOI2015不知多少英雄好汉在裸网络流题上不开longlong挂掉了!
第一次kruscal:首先考虑把所有水泥路连上。如果此时仍不连通,则需要用鹅卵石路连通,这些鹅卵石路是必须要的鹅卵石路(如果>k直接无解);剩下的鹅卵石路都是不必要的。
第二次kruscal:此时的鹅卵石路不一定恰有K条,可能比K条少,于是考虑尽量连不必要的鹅卵石路,直到凑满K条为止(special judge告诉我们输出任意解均可)
第三次kruscal:把剩下的还需要连的水泥路连上。
珠链交换器
应该算是历年APIO最水的一道题了吧……因为没有强制在线(听说有一种把状态串起来的方法,应该是可以对付强制在线的情况,不过那个时候出题人对于强制在线的意识并不强于是就变水题了……)直接把询问排序然后模拟即可。另外我交题的OJ蛋疼地搞了多个q害得我查了半天错……#include<iostream> #include<iomanip> #include<algorithm> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> using namespace std; int n,m,q,c[300005],bead[300005],pos[300005]; struct node{int line,t,id,ans;}ask[300005]; bool Comp(node x,node y) {return x.t<y.t; } bool Comp2(node x,node y) {return x.id<y.id; } void Input() {scanf("%d%d",&n,&m); for(int i=1;i<=m;i++)//交换器 scanf("%d",&c[i]); } void Solve() {ask[0].t=0; while(scanf("%d",&q)!=EOF) {for(int i=1;i<=n;i++)bead[i]=i,pos[i]=i; for(int i=1;i<=q;i++) {scanf("%d%d",&ask[i].line,&ask[i].t); ask[i].id=i; } sort(ask+1,ask+q+1,Comp); for(int i=1;i<=q;i++) {for(int j=ask[i-1].t+1;j<=ask[i].t;j++) {swap(bead[c[j]],bead[c[j]+1]); swap(pos[bead[c[j]]],pos[bead[c[j]+1]]); } ask[i].ans=pos[ask[i].line]; } sort(ask+1,ask+q+1,Comp2); for(int i=1;i<=q;i++)printf("%d\n",ask[i].ans); } } int main() {Input(); Solve(); return 0; }
DNA
首先这题属于计数类DP应该没有异议吧……先把4个字母编号:A=1,C=2,G=3,T=4。不难写出状态转移方程:f[i,j,k]表示后i位(注意是后i位一会要在前面卡),当前位为j,范式为k的方案数。
f[i][j][k]=∑(f[i+1,l,k或k-1])k或k-1视j与l的关系而定,如果j>l则为k-1,否则为k。对于当前为N的位置要枚举当前位,否则不用枚举,直接就是当前的字母对应的数。
统计出方案数之后,就需要“卡”出答案(这是输出第k大解问题的常见思路)。我们从前到后、从小到大枚举数字(如果不是N就不用枚举了),如果当前r能足够减去f[i,j,k](注意这里的k是在从前往后确定答案的过程中根据前面的情况要变化的),就减去,否则说明当前位就是j,确定当前位,然后接着往后枚举。
最后重要的事情说三遍:要开longlong!要开longlong!要开longlong!CQOI2015不知多少英雄好汉在裸网络流题上不开longlong挂掉了!
#include<iostream> #include<iomanip> #include<algorithm> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<map> #define LL long long using namespace std; map<char,LL>mp; map<LL,char>s; LL n,K,r,f[50005][5][12]={0}; char ch[50005]; void Input() {scanf("%lld%lld%lld",&n,&K,&r); scanf("%s",ch+1); mp['A']=1,mp['C']=2,mp['G']=3,mp['T']=4; s[1]='A',s[2]='C',s[3]='G',s[4]='T'; } void Dp() {if(ch =='N')f [1][1]=f [2][1]=f [3][1]=f [4][1]=1; else f [mp[ch ]][1]=1; for(LL i=n-1;i>=1;i--) {if(ch[i]=='N') {for(LL len=1;len<=K;len++) for(LL j=1;j<=4;j++) {for(LL k=1;k<=4;k++) {if(k<j)f[i][j][len]+=f[i+1][k][len-1]; else f[i][j][len]+=f[i+1][k][len]; } } } else {LL x=mp[ch[i]]; for(LL len=1;len<=K;len++) {for(LL k=1;k<=4;k++) {if(k<x)f[i][x][len]+=f[i+1][k][len-1]; else f[i][x][len]+=f[i+1][k][len]; } } } } for(LL i=1;i<=n;i++) for(LL j=1;j<=4;j++) for(LL k=1;k<=K;k++) f[i][j][k]+=f[i][j][k-1]; } void Output() {ch[0]='Q',mp['Q']=0; LL now=K,temp=r,last; for(LL i=1;i<=n;i++) {if(ch[i]!='N') {if(mp[ch[i]]<mp[ch[i-1]])now--; } else {if(ch[i-1]!='N') {LL tnow; for(LL j=1;j<=4;j++) {if(j<mp[ch[i-1]])tnow=now-1; else tnow=now; if(f[i][j][tnow]<temp)temp-=f[i][j][tnow]; else {ch[i]=s[j];now=tnow;break;} } } else {LL tnow; for(LL j=1;j<=4;j++) {if(j<last)tnow=now-1; else tnow=now; if(f[i][j][tnow]<temp)temp-=f[i][j][tnow]; else {ch[i]=s[j];now=tnow;break;} } } } } printf("%s",ch+1); } int main() {Input(); Dp(); Output(); return 0; }
免费道路【上古预警】
这题不难,但是比较考验思维。可以用3次kruscal解决。第一次kruscal:首先考虑把所有水泥路连上。如果此时仍不连通,则需要用鹅卵石路连通,这些鹅卵石路是必须要的鹅卵石路(如果>k直接无解);剩下的鹅卵石路都是不必要的。
第二次kruscal:此时的鹅卵石路不一定恰有K条,可能比K条少,于是考虑尽量连不必要的鹅卵石路,直到凑满K条为止(special judge告诉我们输出任意解均可)
第三次kruscal:把剩下的还需要连的水泥路连上。
#include<iostream> #include<iomanip> #include<algorithm> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> using namespace std; int cnt=0,cnt_must=0,e=0,u=0,n,m,k,father[20005]; struct node{int a,b,c,tag;}edge[100005],ans[100005]; bool comp(node x,node y)//第一步先把鹅卵石路排在后面 {return x.c>y.c; } bool comp2(node x,node y) {return x.c<y.c; } int getfather(int x) {if(father[x]==x)return x; father[x]=getfather(father[x]); return father[x]; } void input() {scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=m;i++) {scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].c); edge[i].tag=0; } } void kruscal1() {for(int i=1;i<=n;i++)father[i]=i; for(int i=1;i<=m;i++) {if(!edge[i].c)continue; int f1=getfather(edge[i].a),f2=getfather(edge[i].b); father[f2]=f1; } for(int i=1;i<=m;i++) {if(edge[i].c==1)continue; int f1=getfather(edge[i].a),f2=getfather(edge[i].b); if(f1!=f2) {father[f2]=f1; edge[i].tag=1; k--; } } } void kruscal2() {int cnt=0; for(int i=1;i<=n;i++)father[i]=i; for(int i=1;i<=m;i++) {if(edge[i].tag==0)continue; int f1=getfather(edge[i].a),f2=getfather(edge[i].b); father[f2]=f1; } for(int i=1;i<=m;i++) {if(edge[i].c==1)continue; int f1=getfather(edge[i].a),f2=getfather(edge[i].b); if(f1!=f2) {k--; father[f2]=f1; edge[i].tag=1; if(k==0)break; } } if(k!=0){printf("no solution");exit(0);} for(int i=1;i<=m;i++) {if(edge[i].c==0)continue; int f1=getfather(edge[i].a),f2=getfather(edge[i].b); if(f1!=f2) { edge[i].tag=1; father[f2]=f1; } } } int main() {input(); kruscal1(); kruscal2(); for(int i=1;i<=m;i++) if(edge[i].tag)printf("%d %d %d\n",edge[i].a,edge[i].b,edge[i].c); return 0; } /* 7 10 6 1 5 0 1 7 0 1 6 1 5 6 1 5 7 1 1 2 0 1 3 0 2 3 1 2 4 1 1 4 0 */
相关文章推荐
- 深度缓冲
- iOS 图形图像动画 Core Animation
- Javascript高级篇-面向对象的特性
- Html5 表单的LocalStorage
- Aerospike系列:7:数据分布详解
- 库函数模拟(二),可变参数列表
- 0414结队--软件再升级(冯铭杰 梁毅乾)
- php设计模式之工厂模式
- iOS彩票项目--第七天,初次读取json数据、KVC转模型技巧、运行时字典转模型以及初步对显示网页的操作并且跟踪标签
- JS return false 与 return true(解决表单重复提交的问题)
- 如何利用云计算技术来实现基于Web的Client-Sever系统的non-stop Sever(灾难恢复)
- Aerospike系列:6:AerospikeTools & Utilities
- 神经网络学习笔记
- 1.3.1 Linux的特色
- 很幽默的讲解六种Socket IO模型 Delphi版本(自己Select查看,WM_SOCKET消息通知,WSAEventSelect自动收取,Overlapped I/O 事件通知模型,Overlapped I/O 完成例程模型,IOCP模型机器人)
- 4.14复利计算再升级总结
- eclipse不能自动编译生成class文件的解决办法
- Android系统权限和root权限
- Aerospike系列:5:安装AMC
- CVE-2015-8660 OverlayFS文件系统权限检查缺陷漏洞