ickchen2

zoj 3397 Change the Major

这个是汉诺塔的变形,思想和汉诺塔一样
但有一个很重要的是某两个点不能直接去,要经过第三个点,如果没用这种情况,递归方程很容易就写出来的。

在递归中,用s,t表示当前点从哪个点出发,到哪个点。如果S=-1,表示刚开始处理的点,如果T=-1,表示下面的点已经处理好了,这个点的目标任意(那肯定是要去自己想去的地方啦:) )因此如果S,T都不为-1的话,就表示是在移动的过程中,这个点的移动只是为了让下面的点移动。因此可以将这个点以上的点看作是一条柱子来处理。计算出N个点一起从某个点到某个点移动的最小次数。


  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<string>
  4 #include<vector>
  5 #include<map>
  6 #include<queue>
  7 #include<algorithm>
  8 #define M 1000
  9 #define clr(x) memset(x,0,sizeof(x))
 10 #define _clr(x) memset(x,-1,sizeof(x))
 11 #define fr(i,a,b) for(int i=a;i<b;++i)
 12 #define pf printf
 13 #define sf scanf
 14 #define pb push_back
 15 #define mp make_pair
 16 #define ll long long
 17 #define debug 1
 18 using namespace std;
 19 int n;
 20 struct person
 21 {
 22     int po,pt,p;
 23     bool operator<(const person &a)const
 24     {
 25         return p<a.p;
 26     }
 27 }p[20];
 28 
 29 ll dp[20][3][3];
 30 int dfs1(int n,int s,int t)
 31 {
 32     if(dp[n][s][t])return dp[n][s][t];
 33     if(n<=0)return 0;
 34     if(n==1)
 35     {
 36         if(s+t==2)
 37             return dp[n][s][t]=2;
 38         else
 39             dp[n][s][t]=1;
 40     }
 41     //return 1;
 42     if(s+t==2)
 43     {
 44         return dp[n][s][t]=3*dfs1(n-1,s,t)+2;
 45     }
 46     return dp[n][s][t]=dfs1(n-1,s,3-s-t)+1+dfs1(n-1,3-s-t,t);
 47 }
 48 ll dfs(int cur,int s,int t)
 49 {
 50     if(cur==n)return 0;
 51     int ss,tt;
 52     if(s!=-1&&t!=-1)
 53     {
 54         //一栋的东西从某一个位置移到某一个位置
 55         if(s==t)
 56         {
 57             ll tem=dfs(cur+1,s,t);
 58             return tem;
 59         }
 60         else
 61         {
 62             ll tem=dfs1(n-cur,s,t);
 63             return tem;
 64         }
 65     }
 66     if(s==-1)ss=p[cur].po;
 67     else ss=s;
 68     if(t==-1)tt=p[cur].pt;
 69     else tt=t;
 70     if(ss==tt)
 71     {
 72         ll tem=dfs(cur+1,s,t);
 73         return tem;
 74     }
 75     if(ss+tt==2)
 76     {
 77         ll tem=dfs(cur+1,s,tt)+1+dfs(cur+1,tt,ss)+1+dfs(cur+1,ss,t);;
 78         return tem;
 79     }
 80 
 81 
 82         ll tem=dfs(cur+1,s,3-ss-tt)+1+dfs(cur+1,3-ss-tt,t);
 83         return tem;
 84 
 85 }
 86 string s[2];
 87 int getM(int pos)
 88 {
 89     if(s[pos][0]=='C')
 90     {
 91         if(s[pos][1]=='o')
 92             return 0;
 93         return 1;
 94     }
 95     return 2;
 96 }
 97 int main()
 98 {
 99     freopen("in.txt","r",stdin);
100     clr(dp);
101     while(sf("%d",&n)>0)
102     {
103         fr(i,0,n)
104         {
105             string point;
106             cin>>s[0]>>s[1]>>point;
107             p[i].po=getM(0);
108             p[i].pt=getM(1);
109             int a,b;
110             sscanf(point.c_str(),"%d.%d",&a,&b);
111             p[i].p=a*100+b;
112             //pf("po=%d pt=%d p=%d\n",po[i],pt[i],p[i]);
113         }
114         sort(p,p+n);
115         pf("%lld\n",dfs(0,-1,-1));
116     }
117     return 0;
118 }
119 

posted on 2010-09-07 22:04 神之子 阅读(229) 评论(0)  编辑 收藏 引用 所属分类: zoj月赛


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(1)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜