zoukankan      html  css  js  c++  java
  • 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
    ",pa[n]);
    134     }
    135     return 0;
    136 }
    View Code
  • 相关阅读:
    洛谷
    洛谷
    洛谷
    模板
    洛谷
    洛谷
    Codeforces Round #561 (Div. 2) E. The LCMs Must be Large(数学)
    Codeforces Round #561 (Div. 2)
    Mail.Ru Cup 2018 Round 2 C. Lucky Days(拓展欧几里得)
    The 10th Shandong Provincial Collegiate Programming Contest H.Tokens on the Segments(贪心+优先级队列 or 贪心+暴力)
  • 原文地址:https://www.cnblogs.com/shangyu/p/3376654.html
Copyright © 2011-2022 走看看