POJ1037A decorative fence(好dp)

1037

带点组合的东西吧

黑书P257 其实我没看懂它写的嘛玩意儿

这题还是挺不错的 一个模糊的思路可能会好想一些 就是大体的递推方程 dp1[][]表示降序 dp2[][]表示升序 数组的含义为长度为i的第一个数为j且相对第一个数为升或降的排列数 当然j肯定要小于等于i的 

dp1[i][j] = dp1[i][j]+dp2[i-1][k](k》=1&&k<j)

同理 dp2[i][j] = dp2[i][j]+dp1[i-1][k](k>=j&&k<i) 这里是因为dp2[i][j]中的j取不到i(因为后面还要升,就肯定取不到i);

这样任务完成了一半了 一定要深刻理解两个dp数组的含义 不然后半部分没法做 

对于确定每一位的长度值 需要一步步的确定 先确定第一位的值 那就是挨个减dp1[n][1]dp2[n][1]..减到小于0时就确定了第一位的值 标记上 同时也确定了整体是升序还是降序 抛开第一位 同样的方式去确定第二位 这里要想清楚一点 因为dp数组里对于长度为i的j都不会大于i 你要找的那个数并不是dp里面的j而是相对第j个没有被标记的数 当然如果是升序 还得大于前一个数 降序还得小于前一个数

不知道为嘛一直TLE 在循环内随便加了个break条件就A了 好神奇~

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<queue>
  7 #include<vector>
  8 #define LL __int64
  9 using namespace std;
 10 LL dp1[22][22],dp2[22][22];
 11 int pa[22];
 12 bool f[22];
 13 int judge(int x)
 14 {
 15     int i,t=0;
 16     for(i = 1; i <= 20 ; i++)
 17     {
 18         if(!f[i]) t++;
 19         if(t==x)
 20         {
 21             f[i] = 1;
 22             return i;
 23         }
 24     }
 25 }
 26 int main()
 27 {
 28     int i,j,g,n,k;
 29     LL c;
 30     scanf("%d",&k);
 31     while(k--)
 32     {
 33         memset(dp1,0,sizeof(dp1));
 34         memset(dp2,0,sizeof(dp2));
 35         memset(f,0,sizeof(f));
 36         scanf("%d%I64d",&n,&c);
 37         dp1[1][1] = dp2[1][1] = 1;
 38         int tt=0;
 39         for(i = 2; i <= n ; i++)
 40         {
 41             for(j = 1; j <= n ; j++)
 42             {
 43                 for(g = 1; g < j ; g++)
 44                 dp1[i][j]+=dp2[i-1][g];
 45                 for(g = j ; g < i ; g++)
 46                 dp2[i][j]+=dp1[i-1][g];
 47             }
 48         }
 49         LL ss=0;
 50         int o=1,ff;
 51         for(i = 1;i <= n ; i++)
 52         {
 53             c-=dp1[n][i];
 54             if(c>0)
 55             {
 56                 c-=dp2[n][i];
 57                 ff = 2;
 58             }
 59             else
 60             {
 61                 ff=1;
 62             }
 63             if(c<=0)
 64             {
 65                 pa[1] = i;
 66                 f[i] = 1;
 67                 if(ff==2)
 68                 c+=dp2[n][i];
 69                 else
 70                 c+=dp1[n][i];
 71                 int y = n-1;
 72                 while(1)
 73                 {
 74                     tt++;
 75                     if(tt>1000)
 76                     break;
 77                     int num=0;
 78                     for(i = 1 ; i <= 20 ; i++)
 79                     {
 80                         if(i==pa[o])
 81                         break;
 82                         if(!f[i]) num++;
 83                     }
 84                     if(ff==2)
 85                     {
 86                         for(i = num+1; i <= y ; i++)
 87                         {
 88                             c-=dp1[y][i];
 89                             if(o==n-1&&c==0)
 90                             {
 91                                 pa[++o] = judge(i);
 92                                 break;
 93                             }
 94                             if(c<=0)
 95                             {
 96                                 c+=dp1[y][i];
 97                                 y--;
 98                                 pa[++o] = judge(i);
 99                                 ff = 1;
100                                 break;
101                             }
102                         }
103                     }
104                     else
105                     {
106 
107                         for(i = 1 ; i <= num ; i++)
108                         {
109                             c-=dp2[y][i];
110                             if(o==n-1&&c==0)
111                             {
112                                 pa[++o] = judge(i);
113                                 break;
114                             }
115                             if(c<=0)
116                             {
117                                 c+=dp2[y][i];
118                                 y--;
119                                 ff = 2;
120                                 pa[++o] = judge(i);
121                                 break;
122                             }
123                         }
124                     }
125                     if(c==0)
126                     break;
127                 }
128                 break;
129             }
130         }
131         for(i = 1 ; i < n ; i++)
132         printf("%d ",pa[i]);
133         printf("%d\n",pa[n]);
134     }
135     return 0;
136 }
View Code

 

posted @ 2013-10-18 20:00  _雨  阅读(198)  评论(0编辑  收藏  举报