zoukankan      html  css  js  c++  java
  • 洛谷 P1514 引水入城

    题意简述

    有一个n*m的矩阵,每个格子都有一个高度,第一行可以放蓄水站,可以向四周比这格高度小的格子送水。问可不可以让第n行都有水,若可以输出最少建几个蓄水站,否则输出第n行最少有几个格子没有水。

    题解思路

    搜索+动态规划

    代码

    #include <queue>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int fx[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    int n, m, ans;
    int d[501], map[501][501];
    bool b[501][501], dp[501][501];
    struct zb{
    	int x, y;
    };
    queue <zb> qq;
    void bfs(int x)
    {
    	memset(b, 0, sizeof(b));
    	b[1][x] = 1;
    	zb xx;
    	xx.x = 1;
    	xx.y = x;
    	qq.push(xx);
    	while (!qq.empty())
    	{
    		zb xx, yy;
    		xx = qq.front();
    		qq.pop();
    		for (int i = 0; i < 4; ++i)
    		{
    			yy = xx;
    			yy.x += fx[i][0];
    			yy.y += fx[i][1];
    			if (yy.x >= 1 && yy.x <= n && yy.y >= 1 && yy.y <= m && !b[yy.x][yy.y] && map[xx.x][xx.y] > map[yy.x][yy.y])
    			{
    				qq.push(yy);
    				b[yy.x][yy.y] = 1;
    			}
    		}
    	}
    	for (int i = 1; i <= m; ++i)
    		for (int j = i; j <= m; ++j)
    			if (b[n][i] && b[n][j])
    				dp[i][j] = 1;
    }
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= n; ++i)
    		for (int j = 1; j <= m; ++j)
    			scanf("%d", &map[i][j]);
    	for (int i = 1; i <= m; ++i)
    	{
    		b[1][i] = 1;
    		zb xx;
    		xx.x = 1;
    		xx.y = i;
    		qq.push(xx);
    	}
    	while (!qq.empty())
    	{
    		zb xx, yy;
    		xx = qq.front();
    		qq.pop();
    		for (int i = 0; i < 4; ++i)
    		{
    			yy = xx;
    			yy.x += fx[i][0];
    			yy.y += fx[i][1];
    			if (yy.x >= 1 && yy.x <= n && yy.y >= 1 && yy.y <= m && !b[yy.x][yy.y] && map[xx.x][xx.y] > map[yy.x][yy.y])
    			{
    				qq.push(yy);
    				b[yy.x][yy.y] = 1;
    			}
    		}
    	}
    	for (int i = 1; i <= m; ++i)
    		if (!b[n][i])
    			ans++;
    	if (ans != 0)
    	{
    		printf("0
    %d
    ", ans);
    		return 0;
    	}
    	for (int i = 1; i <= m; ++i)
    		bfs(i);
    	for (int i = 1; i <= m; ++i)
    		if (dp[1][i]) d[i] = 1;
    		else d[i] = 0x7fffffff;
    	for (int i = 1; i <= m; ++i)
    		for (int j = 1; j <= i; ++j)
    			if (dp[j + 1][i] && d[i] > d[j] + 1)
    				d[i] = d[j] + 1;
    	printf("1
    %d
    ", d[m]);
    }
    
  • 相关阅读:
    Gitblit 的安装使用
    PLSQL 美化规则文件详解
    SQL Server Agent的作用
    使用C#创建Widows服务
    关于VS编译DevExpress默认产生几个多余的语言包的问题解决
    (转)查询A、B表中,A表中存在B表不存在的数据
    子类构造、析构时调用父类的构造、析构函数顺序
    ACCDB与MDB的读取区别
    vue中如何动态添加readonly属性
    windows下生成文件夹目录结构
  • 原文地址:https://www.cnblogs.com/xuyixuan/p/9429554.html
Copyright © 2011-2022 走看看