zoukankan      html  css  js  c++  java
  • noi2005<瑰丽华尔兹>

    链接:https://www.luogu.org/problemnew/show/P2254

    题解:

    思路很好想,若用f[i][j][k]表示k时间到达i,j位置的最大花费 转移即从当前方向转移

    时间复杂度(n*m*t) 空间复杂度(n*m*t)

    注意到题目给出了大T,只有200,n*m*T的时间是可以接受的

    容易发现f[i][j][k]可以由一段t时刻转移而来,而这个可以由单调队列做到o(1)修改

    另外由于可以不动,所以当t2>t1时,t2状态一定优于t1,时间这一维在数组中可以省略

    注意:分4种情况讨论的单调队列不是很好调试,要背清楚模板

    单调队列模板:

    #include <btis/stdc++.h>
    using namespace std;
    int h,t;
    void insert(int x,int y)
    {
         for (int i=t;i>=h;i--)
           if (条件) break;
         q[++i]=y; id[++i]=x; 
    } 
    int main()
    {
        h=1,t=0;{队列的头要在开始处}
        for (int i=1;i<=n;i++)
        {
            if (h<=t&&id[h]+x<i) h++;{要保证元素不为空} 
            //更新
            insert(i,值); 
        }
    }
    View Code

     这道题中的单调队列还需要做一些处理

    方程f[i][j]=max{f[i-k][j]+k}; 我们可以在加入单调队列时对每个元素-j,那么比较时就是等价的,最后再加上j就可以了

    这是一种基本的dp优化

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    int n,m,x,y,k;
    char c;
    const int maxn=500;
    bool f[maxn][maxn];
    int q[maxn],len[maxn],id[maxn],p[maxn],h,t,dp[maxn][maxn],hh[maxn],tt[maxn],fx[maxn];
    void insert(int x,int y)
    {
        int i;
        for (i=t;i>=h;i--)
        {
            if (y<p[i]) break;
        }
        p[++i]=y; t=i;
        id[i]=x;
    }
    int main()
    {
        freopen("noip.in","r",stdin);
        freopen("noip.out","w",stdout);
        cin>>n>>m>>x>>y>>k;
        memset(f,true,sizeof(f));
        for (int i=1;i<=n;i++)
          for (int j=1;j<=m;j++)
          {
              cin>>c;
              if (c=='x') f[i][j]=false;
            }
        for (int i=1;i<=k;i++)
        {
            cin>>hh[i]>>tt[i]>>fx[i];
            len[i]=tt[i]-hh[i]+1;
        }
        memset(dp,-1,sizeof(dp));
        dp[x][y]=0;
      for (int i=1;i<=k;i++)
        {
            if (fx[i]==3)
            {
                for (int j1=1;j1<=n;j1++)
                {
                    h=1;t=0;
                  for (int j2=m;j2>=1;j2--)
                  {
                      if (id[h]-len[i]>j2&&h<=t) h++;
                      if (f[j1][j2]!=0)
                      {
                          int tmp=dp[j1][j2];
                          if (h<=t)
                          { 
                            int x=h;
                            dp[j1][j2]=max(dp[j1][j2],p[x]+m-j2);
                          } 
                          if (tmp!=-1) insert(j2,tmp-(m-j2));
                        } else
                        {
                            h=1;t=0;
                        }
                    }
              }
            }
                    if (fx[i]==4)
            {
                for (int j1=1;j1<=n;j1++)
                {
                    h=1;t=0;
                    for (int j2=1;j2<=m;j2++)
                  {
                      if (id[h]+len[i]<j2&&h<=t) h++;
                      if (f[j1][j2]!=0)
                      {
                          int tmp=dp[j1][j2];
                          if (h<=t)
                          { 
                            int x=h;
                            dp[j1][j2]=max(dp[j1][j2],p[x]+j2);
                          } 
                          if (tmp!=-1) insert(j2,tmp-j2);
                        } else
                        {
                            h=1;t=0;
                        }
                    }
              }
            }
                    if (fx[i]==1)
            {
                for (int j1=1;j1<=m;j1++)
                {
                    h=1;t=0;
                  for (int j2=n;j2>=1;j2--)
                  {
                      if (id[h]-len[i]>j2&&h<=t) h++;
                      if (f[j2][j1]!=0)
                      {
                          int tmp=dp[j2][j1];
                          if (h<=t)
                          { 
                            int x=h;
                            dp[j2][j1]=max(dp[j2][j1],p[x]+n-j2);
                          } 
                          if (tmp!=-1) insert(j2,tmp-(n-j2));
                        } else
                        {
                            h=1;t=0;
                        }
                    }
              }
            }
                    if (fx[i]==2)
            {
                for (int j1=1;j1<=m;j1++)
                {
                    h=1;t=0;
                  for (int j2=1;j2<=n;j2++)
                  {
                      if (id[h]+len[i]<j2&&h<=t) h++;
                      if (f[j2][j1]!=0)
                      {
                          int tmp=dp[j2][j1];
                          if (h<=t)
                          { 
                            int x=h;
                            dp[j2][j1]=max(dp[j2][j1],p[x]+j2);
                          } 
                          if (tmp!=-1) insert(j2,tmp-j2);
                        } else
                        {
                            h=1;t=0;
                        }
                    }
              }
            }
        } 
        int ans=-1;
        for (int i=1;i<=n;i++)
        {
          for (int j=1;j<=m;j++)
          {
              ans=max(ans,dp[i][j]);
            }
       }
        cout<<ans;
    }
    View Code
  • 相关阅读:
    HDU 1242——Rescue(优先队列)
    [LeetCode] Rectangle Area
    iOS 开发百问(6)
    lucene入门查询索引——(三)
    lucene入门创建索引——(二)
    lucene简介——(一)
    Java基础打包以及批处理命令运行
    Maven从私服上下载所需jar包——(十四)
    Maven部署dao工程到私服上——(十三)
    Maven私服安装及配置——(十二)
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8385054.html
Copyright © 2011-2022 走看看