zoukankan      html  css  js  c++  java
  • 题解 【萃香抱西瓜】

    题面

    • 一个 (w imes h) 的矩阵,矩阵中存在可移动的 (0) 点 和 (1)

    • (0)点不可到达,(1) 可到达

    • 给定一个起点 ((sx,sy)), 求给定时间 (T) 内可到达 (m)(1) 所用的最小步数

    数据范围

    (1le h, wle 5, 1le Tle 100, 1le t1le T)

    (2le t, 2le T+1, t1<t2)

    (1le nle 20, 0le mle 10, mle n)

    思路

    • 数据范围不大,可以状压(DP)

    • 用二进制数表示当前已有西瓜的状态,转移时就需要位运算

    • [f[t][i][j][k] ]

    • 表示在 (T) 时刻,坐标为((i ,j))点上已经获得 (k) 个西瓜的最小步数

    • 我们可用以个 (s[t][i][j]) 记录 (T) 时刻,坐标为((i ,j)) 点上可获得西瓜的数量

    • 因此就可方程转移啦

    • [f[t][i][j][k | s[t][i][j]] = min{(f[t - 1][qx][qy][k])+1} ]

    • ((qx qy))表示 (T - 1) 时刻的位置

    • 字面上说,当前状态是由(f[t-1][i][j][k])状态 (+1) 转移来的

    • 初始状态是(f[1][sx][sy][s[1][sx][sy]] = 0),其他为 (INF)

    Code

    #include <iostream>
    #include <cstdio>
    #include <string.h>
    using namespace std;
    typedef long long ll;
    const int inf = 0x3f3f3f3f;
    inline int read() {
      char c = getchar(); int x = 0, f = 1;
      for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
      for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
      return x * f;
    }
    int sum,h,w,t,sx,sy,n,m,t1[manx],t2[manx];
    int dx[5] = {0, 0, 0, 1, -1};
    int dy[5] = {0, 1, -1, 0, 0};
    int s[109][10][10],f[109][10][10][(1 << 10) + 1];
    int main(){
    	h = read();w = read();t = read();sx = read();sy = read();n = read();m = read();
    	//预处理部分 
    	for(int i = 1;i <= n; i++){
    		t1[i] = read();t2[i] = read();
    		int p = read();
    		if(p) sum ++;
    		for(int j = t1[i];j < t2[i]; j++){
    			int x = read(),y = read();
    			if(p == 0) s[j][x][y] = -1;//只要当前时间(x,y)有一个是大西瓜,那么这个格子就不能走 
    			else s[j][x][y] = 1 << (sum - 1);//-1的原因同下 
    		} 
    	}
    	if(s[1][sx][sy] == -1){cout<<-1;return 0;} //特判:落地成盒 
    	ll bz = (1 << m) - 1;//10000000000(10) - 1=111111111(9)
    	memset(f, 0x3f, sizeof (f)); //初始化 
    	f[1][sx][sy][s[1][sx][sy]] = 0;//初始化 
    	//正解开始 
    	for(int i = 2; i <= t;i ++) 
    		for(int x = 1;x <= w;x ++)
    			for(int y = 1; y <= h;y ++){
    				if(s[i][x][y] == -1) continue;
    				for(int j = 0;j <=4; j++){
    					int qx = x + dx[j],qy = y + dy[j];
    					if(qx < 1||qy > h||qy < 1|| qx > w) continue;
    					if(s[i - 1][qx][qy] == -1) continue; 
    					for(int k = 0;k <= bz;k ++){
    						f[i][x][y][k | s[i][x][y]] = min(f[i][x][y][k | s[i][x][y]],
    													   f[i - 1][qx][qy][k] + (j > 0)); //转移方程式 
    					}
    				}
    			}
    	int ans = f[0][0][0][0];
    	for(int x = 1;x <= w; x ++)
    		for(int y = 1;y <= h; y++){
    	 		ans = min(ans,f[t][x][y][bz]); //枚举满足条件的f 
    		 } 
    	if(ans < inf) cout<<ans;
    	else cout<<-1;			
    	return 0;
    }
    
    
    
  • 相关阅读:
    UVA1627-Team them up!(二分图判断+动态规划)
    UVA10817-Headmaster's Headache(动态规划基础)
    UVA1626-Brackets sequence(动态规划基础)
    UVA11584-Partitioning by Palindromes(动态规划基础)
    UVA11584-Partitioning by Palindromes(动态规划基础)
    UVA11400-Lighting System Design(动态规划基础)
    UVA12563-Jin Ge Jin Qu hao(动态规划基础)
    UVA116-Unidirectional TSP(动态规划基础)
    JavaScriptCore框架在iOS7中的对象交互和管理
    iOS7新JavaScriptCore框架入门介绍
  • 原文地址:https://www.cnblogs.com/lToZvTe/p/13931431.html
Copyright © 2011-2022 走看看