zoukankan      html  css  js  c++  java
  • poj1185炮兵阵地 正确代码及错误代码分析

      Solution:状态压缩

    因为设置炮兵的局限性(同行两炮兵相差要大于2),一行10个数最多有60种可能性(程序计算)

      其中判断可能性的好方法是:

             if ((i & (i << 1))==0 && (i & (i << 2))==0
                 && (i & (i >> 1))==0 && (i & (i >> 2))==0)

          代表不能有左1,左2,右1,右2相邻的1

    行数相差2以上,两行互相之间没有影响

      

      if j,k,l不冲突

    f[i][j][k]=max(f[i][j][k],f[i-1][k][l]+v[j])

    其中i为第i行,j为第i行的状态,k为第(i-1)行的状态,l为第(i-2)行的状态,v为在第i行的状态j可以设置的炮兵数

    f[i][j][k]为前i行,以j,k状态下设置的最多的炮兵数,而第i行设置炮兵只与i-1,i-2行有关(前i行中)

    时间复杂度:n*f(t)*f(t)*f(t)

    f(t)为一行t个数,设置炮兵的可能性

    n<=100,m<=10 即 100*60*60*60=21600000

    事实上,由于地形的限制(山地不能建炮兵)和行与行之间的限制(同列两炮兵相差要大于2),时间复杂度小于此

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 int max(int a,int b)
      5 {
      6     if (a>b)
      7         return a;
      8     else
      9         return b;
     10 }
     11 
     12 int main()
     13 {
     14     //100*1024*1024
     15     int i,j,k,l,m,n,f[100][61][61],use[100][61],map[100]={0},s[100],v[1024]={0},ans=0,g=0;
     16     int er[11]={1,2,4,8,16,32,64,128,256,512,1024};
     17     char c;
     18     scanf("%d%d",&m,&n);
     19     scanf("%c",&c);
     20     for (i=0;i<m;i++)
     21     {
     22         for (j=n-1;j>=0;j--)
     23         {
     24             scanf("%c",&c);
     25             if (c=='H')
     26                 map[i]+=er[j];
     27         }
     28         scanf("%c",&c);
     29     }
     30     /*
     31     for (i=0;i<m;i++)
     32         printf("%d
    ",map[i]);
     33     printf("
    ");
     34     */
     35     for (i=0;i<er[n];i++)
     36         if ((i & (i << 1))==0 && (i & (i << 2))==0
     37             && (i & (i >> 1))==0 && (i & (i >> 2))==0)
     38             {
     39                 ans++;
     40                 s[ans]=i;
     41                 j=i;
     42                 while (j)
     43                 {
     44                     j&=(j-1);
     45                     v[ans]++;
     46                 }
     47             }
     48     /*
     49     printf("ans=%d
    ",ans);
     50     for (i=0;i<er[n];i++)
     51         printf("%d %d个 ",s[i],v[i]);
     52     */
     53     //init
     54     for (i=0;i<m;i++)
     55         use[i][0]=0;
     56     for (i=0;i<m;i++)
     57         for (j=1;j<=ans;j++)
     58             for (k=1;k<=ans;k++)
     59                 f[i][j][k]=0;
     60     //row
     61     for (i=0;i<m;i++)
     62         //each row , posibility
     63         for (j=1;j<=ans;j++)
     64             if ((map[i] & s[j])==0)
     65             {
     66                 use[i][0]++;
     67                 use[i][use[i][0]]=j;
     68 
     69                 //编号 cur + bcur + bpre
     70                 if (i>=2)
     71                 {
     72                     for (k=1;k<=use[i-1][0];k++)
     73                         if ((s[j] & s[use[i-1][k]])==0)
     74                             for (l=1;l<=use[i-2][0];l++)
     75                                 if ((s[j] & s[use[i-2][l]])==0
     76                                     && (s[use[i-1][k]] & s[use[i-2][l]])==0)
     77                                         f[i][j][use[i-1][k]]=max(f[i][j][use[i-1][k]],f[i-1][use[i-1][k]][use[i-2][l]]+v[j]);
     78                 }
     79                 else if (i==1)
     80                 {
     81                     for (k=1;k<=use[i-1][0];k++)
     82                         if ((s[j] & s[use[i-1][k]])==0)
     83                             f[i][j][use[i-1][k]]=max(f[i][j][use[i-1][k]],f[i-1][use[i-1][k]][0]+v[j]);
     84                 }
     85                 else
     86                     f[i][j][0]=v[j];
     87 
     88             }
     89     if (m!=1)
     90     {
     91         for (k=1;k<=use[m-1][0];k++)
     92             for (l=1;l<=use[m-2][0];l++)
     93                 if ((s[use[m-1][k]] & s[use[m-2][l]])==0)
     94                     g=max(g,f[m-1][use[m-1][k]][use[m-2][l]]);
     95     }
     96     else
     97     {
     98         for (k=1;k<=use[m-1][0];k++)
     99             g=max(g,f[m-1][use[m-1][k]][0]);
    100     }
    101     printf("%d
    ",g);
    102     /*
    103     for (i=0;i<m;i++)
    104     {
    105         for (j=1;j<=ans;j++)
    106             for (k=1;k<=ans;k++)
    107                 //printf("f[%d][%d][%d]=%d
    ",i,j,k,f[i][j][k]);
    108                 printf("%d ",f[i][j][k]);
    109         printf("
    
    ");
    110     }
    111         for (k=1;k<=use[m-1][0];k++)
    112             for (l=1;l<=use[m-2][0];l++)
    113                 printf("%d %d %d
    ",s[use[m-1][k]],s[use[m-2][l]],f[m-1][use[m-1][k]][use[m-2][l]]);
    114     */
    115     return 0;
    116 }

    错误代码:

      if j,k,l不冲突

      f[i][j]=max(f[i][j],f[i-2][l]+v[k]+v[j]);

    其中i为第i行,j为第i行的状态,k为第(i-1)行的状态,l为第(i-2)行的状态,v为在第i行的状态j可以设置的炮兵数

    f[i][j]为前i行,以j状态下设置的最多的炮兵数

      但是l,k可能会发生冲突,在f[i-2][l]下,第(i-1)行不能用k状态

    第三行,在第1,4个建炮兵情况下,

    8 4

    HPPH   

    PPPP-----是以右上方的P为基础,与第三行发生冲突

    HPPH

    PHHP

    PHHP

    HPPH

    PPPP

    HPPH

     

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 int max(int a,int b)
     5 {
     6     if (a>b)
     7         return a;
     8     else
     9         return b;
    10 }
    11 
    12 int main()
    13 {
    14     int i,j,k,l,m,n,f[100][1024],use[100][60],map[100]={0},s[100],v[1024]={0},ans=0,g=0;
    15     int er[11]={1,2,4,8,16,32,64,128,256,512,1024};
    16     char c;
    17     scanf("%d%d",&m,&n);
    18     scanf("%c",&c);
    19     for (i=0;i<m;i++)
    20     {
    21         for (j=n-1;j>=0;j--)
    22         {
    23             scanf("%c",&c);
    24             if (c=='H')
    25                 map[i]+=er[j];
    26         }
    27         scanf("%c",&c);
    28     }
    29     /*
    30     for (i=0;i<m;i++)
    31         printf("%d
    ",map[i]);
    32     printf("
    ");
    33     */
    34     for (i=0;i<er[n];i++)
    35         if ((i & (i << 1))==0 && (i & (i << 2))==0
    36             && (i & (i >> 1))==0 && (i & (i >> 2))==0)
    37             {
    38                 ans++;
    39                 s[ans]=i;
    40                 j=i;
    41                 while (j)
    42                 {
    43                     j&=(j-1);
    44                     v[i]++;
    45                 }
    46             }
    47     /*
    48     printf("ans=%d
    ",ans);
    49     for (i=0;i<er[n];i++)
    50         printf("%d ",v[i]);
    51     */
    52     for (i=0;i<m;i++)
    53         use[i][0]=0;
    54     for (i=0;i<m;i++)
    55         for (j=0;j<er[i];j++)
    56             f[i][j]=0;
    57     //row
    58     for (i=0;i<m;i++)
    59     {
    60         //each row , posibility
    61         for (j=1;j<=ans;j++)
    62             if ((map[i] & s[j])==0)
    63             {
    64                 use[i][0]++;
    65                 use[i][use[i][0]]=s[j];
    66                 if (i>=2)
    67                 {
    68                     for (k=1;k<=use[i-1][0];k++)
    69                         if ((s[j] & use[i-1][k])==0)
    70                             for (l=1;l<=use[i-2][0];l++)
    71                                 if ((s[j] & use[i-2][l])==0
    72                                     && (use[i-1][k] & use[i-2][l])==0)
    73         f[i][s[j]]=max(f[i][s[j]],f[i-2][use[i-2][l]]+v[use[i-1][k]]+v[s[j]]);
    74                 }
    75                 else if (i==1)
    76                 {
    77                     for (k=1;k<=use[i-1][0];k++)
    78                         if ((s[j] & use[i-1][k])==0)
    79         f[i][s[j]]=max(f[i][s[j]],f[i-1][use[i-1][k]]+v[s[j]]);
    80                 }
    81                 else
    82                     f[i][s[j]]=v[s[j]];
    83             }
    84     }
    85     for (i=1;i<=use[m-1][0];i++)
    86         g=max(g,f[m-1][use[m-1][i]]);
    87     printf("%d
    ",g);
    88     /*
    89     for (i=0;i<m;i++)
    90     {
    91         for (j=0;j<er[n];j++)
    92             printf("%d ",f[i][j]);
    93         printf("
    ");
    94     }
    95     */
    96     return 0;
    97 }
  • 相关阅读:
    HTML5中video的使用一
    sql存储过程的简单使用
    Linq to Sqlite连接
    linq to sql简单使用
    练习笔记:net,JqueryUI实现自动补全功能
    三个师妹之出题
    Docker——questions
    Docker——网络
    Docker——dockerfile
    Docker——容器数据卷
  • 原文地址:https://www.cnblogs.com/cmyg/p/6542253.html
Copyright © 2011-2022 走看看