【scoi2009】围豆豆(最短路模型)
洛谷题面:https://www.luogu.org/problemnew/show/P2566
由每个豆子引一条射线,与射线交点个数为奇数相当于多边形围住了它,这样可以定义一个状态f[x][y][s]表示从起点出发,走到(x,y)处时的路径与D颗豆子引出的射线相交的奇偶性状态为s,最少需多少步。然后跑最短路转移即可。
然而,有一个小问题就是转移时如何判与豆子引出的射线相交。如果单纯按与线相交的拐点来计算的话,我们发现会有这两种截然不同的情况被算成了一样。

理论上蓝色路径应该是0,绿色路径应该是1才对。
于是我们可以选择统计时把边定一下向,像绿色路径这种穿出的情况就不重复计算了。详见代码。
#include<bits/stdc++.h>
using namespace std;
const int N = 15;
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,b) for(register int i=(a);i<=(b);++i)
int n,m,w[N],val[1<<10],D;
char mp[N][N];
int dis[N][N][1<<10],ans;
struct la{int x,y,s;}bean[N];
queue<la> q;
bool vis[N][N][1<<10];
int rx[4]={0,1,0,-1};
int ry[4]={1,0,-1,0};
inline bool isin(int x,int y){return x>=1&&x<=n&&y>=1&&y<=m;}
inline void spfa(int x,int y){
    memset(dis,0x3f,sizeof(dis));
    q.push((la){x,y,0});dis[x][y][0]=0;vis[x][y][0]=1;
    while(!q.empty()){
        la u=q.front();q.pop();vis[u.x][u.y][u.s]=0;
        rep(i,0,3){
            int nx=u.x+rx[i],ny=u.y+ry[i],ns=u.s;
            if(!isin(nx,ny)||mp[nx][ny]!='0')continue;
            rep(j,0,D-1){
                if(ny>bean[j].y&&((nx==bean[j].x&&u.x>bean[j].x)||(nx>bean[j].x&&u.x==bean[j].x)))ns^=(1<<j);
            }
            if(dis[nx][ny][ns]>dis[u.x][u.y][u.s]+1){
                dis[nx][ny][ns]=dis[u.x][u.y][u.s]+1;
                if(vis[nx][ny][ns])continue;
                vis[nx][ny][ns]=1;
                q.push((la){nx,ny,ns});
            }
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    scanf("%d",&D);
    rep(i,0,D-1){
        scanf("%d",&w[i]);
    }
    rep(j,0,(1<<D)-1){
        rep(i,0,D-1){
            if(j&(1<<i))val[j]+=w[i];
        }
    }
    rep(i,1,n){
        scanf("%s",mp[i]+1);
        rep(j,1,m){
            if(mp[i][j]>'0')bean[mp[i][j]-'0'-1]=(la){i,j,0};
        }
    }
    rep(i,1,n){
        rep(j,1,m){
            if(mp[i][j]!='0')continue;
            spfa(i,j);
            rep(k,0,(1<<D)-1)ans=max(ans,val[k]-dis[i][j][k]);
        }
    }
    printf("%d\n",ans);
    return 0;
}
												
											【scoi2009】围豆豆(最短路模型)的更多相关文章
- 【BZOJ1294】[SCOI2009]围豆豆Bean 射线法+状压DP+SPFA
		
[BZOJ1294][SCOI2009]围豆豆Bean Description Input 第一行两个整数N和M,为矩阵的边长. 第二行一个整数D,为豆子的总个数. 第三行包含D个整数V1到VD,分别 ...
 - 【BZOJ1294】[SCOI2009]围豆豆(动态规划,状压)
		
[BZOJ1294][SCOI2009]围豆豆(动态规划,状压) 题面 BZOJ 洛谷 题解 首先考虑如何判断一个点是否在一个多边形内(不一定是凸的),我们从这个点开始,朝着一个方向画一条射线,看看它 ...
 - [BZOJ1294][SCOI2009]围豆豆Bean  射线法+状压dp+spfa
		
1294: [SCOI2009]围豆豆Bean Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 458 Solved: 305[Submit][Sta ...
 - 洛谷P2566 [SCOI2009]围豆豆(状压dp+spfa)
		
题目传送门 题解 Σ(っ °Д °;)っ 前置知识 射线法:从一点向右(其实哪边都行)水平引一条射线,若射线与路径的交点为偶数,则点不被包含,若为奇数,则被包含.(但注意存在射线与路径重合的情况) 这 ...
 - BZOJ1294: [SCOI2009]围豆豆Bean
		
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1294 状压dp,dis[s][i][j]表示从(i,j)出发围的状态是s的最短路. 然后判断一 ...
 - [SCOI2009]围豆豆
		
Description Input 第一行两个整数N和M,为矩阵的边长. 第二行一个整数D,为豆子的总个数. 第三行包含D个整数V1到VD,分别为每颗豆子的分值. 接着N行有一个N×M的字符矩阵来描述 ...
 - 【题解】SCOI2009围豆豆
		
很久之前就很想做的一道题,一直思考到今天才下定决心看题解.这道题中,很关键的一点就在于:如何判断一个点是否在一个多边形内?其实如果计算几何基本功扎实的话,应该是可以很快给出答案的(可惜我完全不行):由 ...
 - BZOJ 1294 [SCOI2009]围豆豆Bean ——计算几何
		
显然我们不可能表示出一台路径,因为实在是太复杂了. 所以我们可以记录一下路径对答案的影响,显然路径对答案影响相同的时候,答案更优,所以我们可以用影响来代替路径. 所以我们考虑状压一下所有的豆子有没有被 ...
 - 【状态压缩DP】SCOI2009 围豆豆
		
题目大意 洛谷链接 在一个\(N×M\)的矩阵方格内分布着\(D\)颗豆子,每颗豆有不同的分值\(V_i\).游戏者可以选择任意一个方格作为起始格,每次移动可以随意的走到相邻的四个格子,直到最终又回到 ...
 - 【BZOJ】1294: [SCOI2009]围豆豆Bean
		
题解 随机跳题真好玩 这个就是考虑我们怎么判断点在多边形内,就是点做一条射线,穿过了奇数条边 我们只需要记录一个二进制状态表示每个点的射线穿过路径的次数的奇偶性 枚举起点,然后用BFS的方式更新dp状 ...
 
随机推荐
- js判断object的具体类型(或者说判断object的类class)
			
The JavaScript specification gives exactly one proper way to determine the class of an object: Objec ...
 - [Vue-rx] Access Events from Vue.js Templates as RxJS Streams with domStreams
			
The domStreams component property enables you to access Events from your Vue.js templates as Streams ...
 - Navicat 提示Cannot create oci environment  解决方式
			
一直在使用Navicat,这是一个数据库client软件.能连接多种不同类型的数据库,给我们的日常的工作带来了不少的便捷.近期.我在电脑上安装了orcale,然后,Navicat就莫名其妙的不能连接o ...
 - Swift基础(类,结构体,函数)
			
import Foundation // 创建一个类 class Student { // 属性(类的属性必须赋初值,如果不赋值,需要写自定义方法) var studentName: String v ...
 - spring与springboot中,如何在static方法里使用自动注入的属性
			
第一步:写注解@Component 使当前类成为一个bean对象.(@Controller,@service都行) 第二步:写个static的变量 第三步:写个@PostConstruct注解注解注释 ...
 - android按钮被点击文字颜色变化效果
			
有的时候做应用需要点击按钮时文字颜色也跟着变,松开后又还原,目前发现两种解决方案:第一用图片,如果出现的地方比较多,那么图片的量就相当可观:第二,也就是本文讲到的.废话少说,先贴图片,再上代码. 正常 ...
 - Linux下查看操作系统的位数和系统名称版本信息
			
Linux下如何明确地查看操作系统的位数 如何知晓操作系统是32位还是64位?这里介绍一种简单的方式: [plain] [root@localhost mysql-5.1.57]# getconf L ...
 - 【STM32H7教程】第23章      STM32H7的MPU内存保护单元(重要)
			
完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第23章 STM32H7的MPU内存保护单元 ...
 - WinSocket简单聊天程序客户端
			
#pragma comment(lib,"Ws2_32.lib") #include <stdio.h> #include <Winsock2.h> SOC ...
 - JavaScript 判断手机端操作系统(Andorid/IOS)
			
androidURL = "http://xxx/xxx.apk"; var browser = { versions: function() { var u = navigato ...