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

 

你可能感兴趣的:(poj)