题意:有一个字符串s[1] 一个字符串 s[2],s[k]  = s[k-1] + s[k-2] , 给你 K(第几个字符串)  ,x(‘AC'的个数),  n(s[1]的长度),m (s[2]的长度)。构造S[1] ,S[2]使得满足条件

解题思路:状压 + dp,枚举 s[1] 中S[2]中AC的个数,再枚举交叉时候增加的AC个数,然后进行dp,细节太多了,名副其实的蘑菇题,本来以为就我一个人一大坨代码,结果发现其他人都是的。。。要哭。

解题代码:

  1 // File Name: 379d.cpp
  2 // Author: darkdream
  3 // Created Time: 2015年03月30日 星期一 16时33分13秒
  4 
  5 #include<vector>
  6 #include<list>
  7 #include<map>
  8 #include<set>
  9 #include<deque>
 10 #include<stack>
 11 #include<bitset>
 12 #include<algorithm>
 13 #include<functional>
 14 #include<numeric>
 15 #include<utility>
 16 #include<sstream>
 17 #include<iostream>
 18 #include<iomanip>
 19 #include<cstdio>
 20 #include<cmath>
 21 #include<cstdlib>
 22 #include<cstring>
 23 #include<ctime>
 24 #define LL long long
 25 
 26 using namespace std;
 27 LL k , p, n , m ;
 28 LL dp[100][5];
 29 LL tmp[10];
 30 LL ok  = 0 ; 
 31 void print(char str[],LL num,LL len)
 32 {
 33 //    printf("%I64d %I64d\n",num,len);
 34     if(str[1] == 'C')
 35     {
 36       for(LL i = 2;i <= 2*num;i +=2)
 37       {
 38          str[i] = 'A';
 39          str[i+1] = 'C';
 40       }
 41       for(LL i = 2*num + 2;i <= len-1;i ++)
 42           str[i] = 'Z';
 43     }else{
 44       for(LL i = 1;i <= 2*num;i +=2)
 45       {
 46          str[i] = 'A';
 47          str[i+1] = 'C';
 48       }
 49       for(LL i = 2*num + 1;i <= len-1;i ++)
 50           str[i] = 'Z';
 51     }
 52     for(LL i = 1;i <= len ;i ++)
 53         printf("%c",str[i]);
 54     printf("\n");
 55 }
 56 LL solve(LL x , LL y , LL status)
 57 {
 58   LL hehe = status; 
 59    memset(dp,0,sizeof(dp)) ;
 60    LL tt = 0 ; 
 61    memset(tmp,0,sizeof(tmp));
 62    while(status)
 63    {
 64       tt ++ ; 
 65       tmp[tt] = status %2; 
 66       status /= 2;
 67    }
 68    LL tx;
 69    LL ty;
 70    tx = ty = 0 ;
 71    if(tmp[2] && tmp[3])
 72        tmp[4] = 1; 
 73    if(tmp[1])
 74    {
 75       return 0;
 76       tx += 2;
 77    }
 78    if((tmp[2] || tmp[3]) && (tmp[2] != tmp[3]))
 79    {
 80       tx ++;
 81       ty ++ ;
 82    }
 83    if(tmp[2] && tmp[3])
 84    {
 85       tx += 2; 
 86       ty +=2;
 87    }
 88    if(tmp[4]&& tmp[3] == 0)
 89    {
 90       ty += 2 ;
 91    }
 92    if(x *2 + tx > n)
 93        return 0 ; 
 94    if(y*2 + ty > m)
 95        return 0;
 96   // printf("%I64d %I64d %I64d\n",x,y,status);
 97    memset(dp,0,sizeof(dp));
 98    dp[1][1] = x; 
 99    dp[2][1] = y;
100    dp[3][1] = x+ y ;
101    dp[3][3] = tmp[2]; 
102    for(LL i = 4; i <= k ;i ++)
103    {
104        for(LL j = 1;j <= 5;j ++)
105            dp[i][j] += dp[i-1][j] + dp[i-2][j];
106        if(i % 2 == 0)
107            dp[i][4] += tmp[3];
108        else dp[i][5] += tmp[4]; 
109    }
110    LL tsum = 0 ; 
111    for(LL j = 1;j<= 5;j ++)
112        tsum += dp[k][j];
113   //printf("%I64d %I64d %I64d %I64d\n",tsum,x,y,hehe);
114    if(tsum != p)
115        return 0 ;
116    char ansa[105];
117    char ansb[105];
118    memset(ansa,0,sizeof(ansa));
119    memset(ansb,0,sizeof(ansb));
120    if(tmp[1])
121    {
122       ansa[1] = 'C'; 
123       ansa[n] = 'A';
124    }
125    if(tmp[2])
126    {
127       ansa[n] = 'A';
128       ansb[1] = 'C';
129    }
130    if(tmp[3])
131    {
132       ansa[1] = 'C';
133       ansb[m] = 'A';
134    }
135    if(tmp[4])
136    {
137       ansb[1] = 'C';
138       ansb[m] = 'A';
139    }
140    if(ansa[n] == '\0')
141        ansa[n] ='Z';
142    if(ansb[m] == '\0')
143        ansb[m] ='Z';
144    print(ansa,x,n);
145    print(ansb,y,m);
146    return 1;
147 }
148 int main(){
149       scanf("%I64d %I64d %I64d %I64d",&k,&p,&n,&m);
150       for(LL i = 0;i <= n/2;i ++)
151       {
152           for(LL j = 0;j <= m/2;j ++)
153           {
154              for(LL s = 0 ; s<= 15; s ++)
155               if(solve(i,j,s))
156                   return  0 ;
157           }
158       }
159       printf("Happy new year!\n");
160 return 0;
161 }
View Code

 

posted on 2015-03-30 22:52  dark_dream  阅读(147)  评论(0编辑  收藏  举报