HDU6223 Infinite Fraction Path bfs+剪枝
这个题第一次看见的时候,题意没搞懂就没做,这第二次也不会呀。。
题意:第i个城市到第(i*i+1)%n个城市,每个城市有个权值,从一个城市出发走N个城市,就可以得到一个长度为N的权值序列,求字典序最大的序列。
首先因为每个城市的出度为1,所以从任意城市出发都可以走出N步,通过打表可以发现度数为0的点几乎占了10分之9,也就是说大部分都是相同重复的部分。
虽然经过了一系列分析,但这并没有任何用,写了一发暴力dfs,T了。然后题解做题法,有几个解法,一个是鲲鲲有想到,但是卡常,我也不会。然后第二个就是bfs+剪枝。
有想到是搜索+剪枝,但一直想是怎么dfs记忆化,唉,太菜了。然后bfs很好理解,我们就按照深度的优先级一层层向下走,然后第一个剪枝就是,当前层已经保存的答案要是大于目前这个位置的权值,
那么很明显当前这个位置没必要扩展下去了,然后如果这个位置已经到过比现在更深的深度,那么有当前深度当那个深度之间的答案,已经被更新过了,那也没必要扩展了。
1 #include<cstdio> 2 #include<queue> 3 using namespace std; 4 const int N=2e5+11; 5 char mp[N]; 6 int n,maxv,ne[N],dep[N],val[N],ans[N]; 7 struct Node{ 8 int pos,dep; 9 Node(){} 10 Node(int pos,int dep):pos(pos),dep(dep){} 11 bool operator<(const Node &n1)const{ 12 return dep==n1.dep ? val[pos]<val[n1.pos] : dep>n1.dep; 13 } 14 }qn; 15 void init(){ 16 maxv=0; 17 for(int i=0;i<=n;i++){ 18 dep[i]=ans[i]=-1; 19 val[i]=mp[i]-'0'; 20 maxv=max(maxv,val[i]); 21 ne[i]=(1ll*i*i+1)%n; 22 } 23 } 24 void bfs(){ 25 priority_queue<Node> q; 26 for(int i=0;i<n;i++) 27 if(val[i]==maxv) q.push(Node(i,0)); 28 while(!q.empty()){ 29 qn=q.top(); 30 q.pop(); 31 if(ans[qn.dep]==-1) ans[qn.dep]=val[qn.pos]; 32 else if(ans[qn.dep]>val[qn.pos]) continue; 33 if(dep[qn.pos]<qn.dep) dep[qn.pos]=qn.dep; 34 else continue; 35 if(qn.dep==n-1) continue; 36 q.push(Node(ne[qn.pos],qn.dep+1)); 37 } 38 } 39 int main(){ 40 int t=1,T; 41 scanf("%d",&T); 42 while(t<=T){ 43 scanf("%d",&n); 44 scanf("%s",mp); 45 init(); 46 bfs(); 47 printf("Case #%d: ",t++); 48 for(int i=0;i<n;i++) printf("%d",ans[i]); 49 printf("\n"); 50 } 51 return 0; 52 }
我太难了~给个三连吧,亲~~~