• BZOJ1930 [Shoi2003]pacman 吃豆豆


       dp,首先建出图,f[i][j]表示a吃到了i点,b吃到了j点的最大值,转移的时候转移拓扑序小的那一维,如果i拓扑序小于j,那么转移到f[k][j],否则转移到f[i][k],建出的图边数也要优化,不然会超时。优化的方法是假如i,j连边,那么如果有一条边(i,k),x[k]>x[j]并且y[k]>y[j]那么(i,k)这条边就没有必要存在了。因为先取(i,j)在去(j,k)会比直接取(i,k)要好。

    代码

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define N 10010
     4 using namespace std;
     5 int n,i,j,rd[N],t,w,tot,id[N];
     6 int dp,pre[3000000],p[N],tt[3000000],z[N],ID[N],tmp;
     7 int f[2500][2500];
     8 struct g{
     9     int x,y;
    10 }a[N];
    11 bool cmp(g a,g b)
    12 {
    13     if (a.x==b.x)
    14     return a.y<b.y;
    15     return a.x<b.x;
    16 }
    17 void link(int x,int y)
    18 {
    19     dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;
    20 }
    21 void Dp(int x,int y)
    22 {
    23     int i;
    24     i=p[x];
    25     while (i)
    26     {
    27             int a=tt[i],b=y;
    28             if (id[a]>id[b])
    29             swap(a,b);
    30             if (a!=b)
    31             f[a][b]=max(f[a][b],f[x][y]+1);
    32             else
    33             f[a][b]=max(f[a][b],f[x][y]);
    34         i=pre[i];
    35     }
    36 }
    37 int main()
    38 {
    39     scanf("%d",&n);
    40     
    41     for (i=1;i<=n;i++)
    42         scanf("%d%d",&a[i].x,&a[i].y);
    43     sort(a+1,a+1+n,cmp);
    44     for (i=1;i<=n;i++)
    45     {
    46     tmp=0x37373737*2;
    47     for (j=i+1;j<=n;j++)
    48     if ((i!=j)&&(a[i].x<=a[j].x)&&(a[i].y<=a[j].y)&&(a[j].y<tmp))
    49     {
    50         tmp=a[j].y;
    51         rd[j]++;
    52          link(i,j);
    53     }
    54     }
    55     for (i=1;i<=n;i++)
    56     {
    57         link(0,i);rd[i]++;
    58         link(i,n+1);rd[n+1]++;
    59     }
    60     t=0;w=1;z[w]=0;
    61     while (t!=w)
    62     {
    63         tot++;
    64                 t++;
    65         id[z[t]]=tot;
    66         ID[tot]=z[t];
    67         i=p[z[t]];
    68         while (i)
    69         {
    70             rd[tt[i]]--;
    71             if (rd[tt[i]]==0)
    72             {
    73                 w++;z[w]=tt[i];
    74             }
    75             i=pre[i];
    76         }
    77     }
    78 
    79     
    80     for (i=1;i<=tot;i++)
    81         for (j=i;j<=tot;j++)
    82             Dp(ID[i],ID[j]);
    83     printf("%d
    ",f[n+1][n+1]-1);
    84 }
  • 相关阅读:
    【设计模式】——抽象工厂模式
    【设计模式】——观察者模式
    Candy
    Two Sum
    Interleaving String
    Longest Valid Parentheses
    【设计模式】——建造者模式
    【设计模式】——外观模式
    Simplify Path
    Word Search
  • 原文地址:https://www.cnblogs.com/fzmh/p/4860654.html
Copyright © 2020-2023  润新知