• 洛谷3956dp


    题目描述

    借鉴了一下dalao的思路w

    自加注释学习一下~

    #include<bits/stdc++.h> 
    using namespace std;
    const int MAXN= 210;//数组最大长度 
    const int inf=99999999;//正无穷 
    int w[MAXN][MAXN];//记录颜色 
    int m,n,x,y,z;
    int ans=99999999;
    int f[MAXN][MAXN][3][2];//f[i][j][k][l]表示到达(i,j)且颜色为k时的最小花费,l=0表示刚用过金币,1刚没用过 
    int main()
    {
        int i,j,k,l;
        scanf("%d%d",&m,&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d%d%d",&x,&y,&z);//坐标为(x,y)的格子有颜色 z 
            w[x][y]=z+1;
    		//这步操作后,2是黄色,1是红色,0是无色 
        }
        memset(f,127/3,sizeof(f));//初始化为极大值 
        f[1][1][w[1][1]][1]=0;//dp初始化位置 
        int T=4;
        while(T--)
        //要循环四次!因为在更新格子时,是来自上下左右四个方向
    	//所以没有方向,也就是说,在计算某格子右方或下方的格子时
    	//它的最小值可能会改变
    	//循环四次的话就会改过来 
        for(i=1;i<=m;i++)
          for(j=1;j<=m;j++)
          {
              if(i==1&&j==1) continue;//不能对第一个格子操作 
              if(w[i][j])//有颜色 
              {
                for(k=1;k<=2;k++)
                for(l=0;l<=1;l++)
                  if(w[i][j]==k)//颜色相同 
                  {
                      int temp=f[i][j][k][1];
                      f[i][j][w[i][j]][1]=min(f[i-1][j][k][l],min(f[i][j-1][k][l],min(f[i][j+1][k][l],f[i+1][j][k][l])));
                      //四个方向来的最小值 
                      f[i][j][w[i][j]][1]=min(temp,f[i][j][k][1]);
    				  //和之前比较 
                  }
                  else//颜色不同 
                  {
                      int temp=f[i][j][w[i][j]][1];
                      f[i][j][w[i][j]][1]=min(f[i-1][j][k][l],min(f[i][j-1][k][l],min(f[i][j+1][k][l],f[i+1][j][k][l])))+1;
                      f[i][j][w[i][j]][1]=min(temp,f[i][j][w[i][j]][1]);
                  }
            }
            else//没有颜色,魔法! 
            for(int k=1;k<=2;k++)
            {
                int temp=f[i][j][k][0];
                f[i][j][k][0]=min(f[i-1][j][k][1],min(f[i][j-1][k][1],min(f[i][j+1][k][1],f[i+1][j][k][1])))+2;
                //注意,这里没有l的循环,因为不能连续使用魔法 
                f[i][j][k][0]=min(temp,f[i][j][k][0]);
                //因为前面有个+2,所以要分开判断比较容易w 
            }
          }
        ans=min(ans,min(f[m][m][1][1],min(f[m][m][1][0],min(f[m][m][2][1],f[m][m][2][0]))));//右下角格子是四种情况的最小值 
        if(ans==inf)//其实就是无解 
        printf("-1\n");
        else
        printf("%d\n",ans);
        return 0;
    }
    

    qwqwqwq
  • 相关阅读:
    智能指针unique_ptr记录
    ubuntu系统火狐无法播放网页视频
    javascript中json对象json数组json字符串互转及取值
    C#压缩文件
    C#异步编程
    C# POST请求 json格式
    C# Http方式下载文件到本地类
    C#中NPOI操作excel之读取和写入excel数据
    浅析C#中抽象类和接口的区别
    C#自动实现Dll(OCX)控件注册的两种方法
  • 原文地址:https://www.cnblogs.com/erutsiom/p/9905164.html
Copyright © 2020-2023  润新知