zoukankan      html  css  js  c++  java
  • UVA 1408 Flight Control

    https://vjudge.net/problem/UVA-1408

    题目

    有个很神奇的雷达,可以得到当前时刻$n imes m$格里面的飞机的能量。每个格子里面任何时间都只会有1架飞机。格子里面的能量反映了飞机的轨迹,飞机是按照能量递减的方向飞行的,只能沿着横向或纵向飞行,并且中途不能改变方向。如果能量为0,表示这个格子里面没有飞过飞机。给出当前的能量图,问从这张图里面能输出最少多少架飞机。

    $1leqslant nleqslant 50, 1leqslant mleqslant 9$

    样例输入

    3 3
    1 2 3
    4 5 6
    7 8 9
    
    0 0
    

    样例输出

    Case 1: 3
    

    题解

    训练指南说这是一道入门题= =然后发现我状态设的很差

    一开始设状态为当前格子放“<”“>”“^”“v”四种或不放,时间复杂度$5^{n imes m} imes 8$(开头和继续)

    然后就不知道怎么优化了

    实际上可以剪枝

    把开头、不放全部合成成1个“o”,横向“<”“>”合成成“-”,纵向“^”“v”合成成“|”

    为了区分继续的方向,可以对三个元素进行判断(这个时候一定有三个元素)

    还有一个问题是一个开头只能用一次,不能横向和纵向都接上,因此接纵向的时候判断右边没有接上横向就可以了

    AC代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cctype>
    #include<unordered_map>
    #define REP(i,a,b) for(register int i=(a); i<(b); i++)
    #define REPE(i,a,b) for(register int i=(a); i<=(b); i++)
    #define PERE(i,a,b) for(register int i=(a); i>=(b); i--)
    using namespace std;
    typedef long long ll;
    int nrow, ncol;
    unordered_map<unsigned, int> dp[57][9];
    int mp[57][9];
    int kase=0;
    inline unsigned setmask(unsigned k, int v, int d) {
    	unsigned msk=7<<(v*3);
    	k &= ~msk;
    	k |= d<<(v*3);
    	return k;
    }
    inline unsigned getmask(unsigned k, int v) {
    	return (k>>(v*3))&7;
    }
    inline bool can(int a, int b, int c) {
    	if(a<b && b<c) return true;
    	if(a>b && b>c) return true;
    	return false;
    }
    int calc(int r, int c, unsigned F) {
    	if(c==ncol) {r++; c=0;}
    	if(r==nrow) return 0;
    	if(mp[r][c]==0) return calc(r, c+1, setmask(F, c, 0));
    	if(dp[r][c].count(F)) return dp[r][c][F];
    	int ans=0x3f3f3f3f;
    	ans = 1+calc(r, c+1, setmask(F, c, 0));
    	
    	if(c && mp[r][c-1]) {
    		unsigned t=getmask(F,c-1);
    		if(t==0 && mp[r][c-1]!=mp[r][c]) {
    			ans = min(ans, calc(r, c+1, setmask(F, c, 1)));
    		} else if(t==1 && can(mp[r][c-2], mp[r][c-1], mp[r][c])) {
    			ans = min(ans, calc(r, c+1, setmask(F, c, 1)));
    		}
    	}
    	if(r && getmask(F,c+1)!=1 && mp[r-1][c]) {
    		unsigned t=getmask(F,c);
    		if(t==0 && mp[r-1][c]!=mp[r][c]) {
    			ans = min(ans, calc(r, c+1, setmask(F, c, 2)));
    		} else if(t==2 && can(mp[r-2][c], mp[r-1][c], mp[r][c])) {
    			ans = min(ans, calc(r, c+1, setmask(F, c, 2)));
    		}
    	}
    	
    	dp[r][c][F]=ans;
    	return ans;
    }
    int main() {
    	while(~scanf("%d%d", &nrow, &ncol) && nrow) {
    		REP(i,0,nrow) REP(j,0,ncol) {
    			scanf("%d", &mp[i][j]);
    		}
    		REP(i,0,nrow) REP(j,0,ncol) dp[i][j].clear();
    		int ans=calc(0,0,0);
    		kase++;
    		printf("Case %d: %d
    ", kase, ans);
    		
    	}
    	return 0;
    }
    
  • 相关阅读:
    关于编码问题
    期中架构之前所有的命令-总结
    Bootstrap表格添加搜索栏
    Bootstrap表格分页(二)
    Bootstrap表格分页(一)
    Entity Framework 分页处理
    Protocol Buffers v3.0.0编译安装小记
    golang学习笔记
    Java 对象生命周期
    Java 操作符
  • 原文地址:https://www.cnblogs.com/sahdsg/p/12325516.html
Copyright © 2011-2022 走看看