题目大意:
给你一张网个图,每个位置是空地、障碍、炸弹、宝藏、起点之一。
规划一条从其点出发不包含炸弹的闭合路线(回路),并可获得最大的利润。
利润定义为路线内部的宝藏收益(可能为负数)之和减去路径长度(可以不走)。注意路线可以自交。
为了确定一个格子是否在这条路线里面,请使用以下算法判断:1.假设该点的坐标为需要判断的点为 p(i,j) ,该点不在路线上。2.从该点往任意方向作一条射线,如果与路线相交奇数次,我们就认为这个格子在这条路线里面,否则这个格子在这条路线外面。
n,m≤20,t≤8,∣value∣≤200n,m\le20,t\le8,|value|\le200n,m≤20,t≤8,∣value∣≤200,其中ttt为宝藏和障碍的数量之和。
题解:
考虑dp(虽然最后不需要),显然你会设dp(x,y,s)表示现在在(x,y),已经收集了恰好s这个集合的宝藏的最短路。发现不能确定s的转移,gg。
然后意识到对于一个宝藏的判定等价于引出一条射线并判定交点个数奇偶,然后钦定所有射线的方向(我是钦定了上偏右60度角),然后状压这个奇偶性,最后bfs一波确定每个状态的值即可。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<climits>
#include<cmath>
#include<assert.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define INF (INT_MAX/20-10)
#define inf (INT_MIN/20+10)
#define MXA 23
#define MXS 280
#define N MXA*MXA*MXS
#define M (N*4)
#define db double
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
const db sqrt3=sqrt(3);
struct edges{int to,pre;
}e[M];int h[N],etop,id[MXA][MXA][MXS],d[N],a[MXA][MXA];queue<int> q;
inline int add_edge(int u,int v) { return e[++etop].to=v,e[etop].pre=h[u],h[u]=etop; }
struct P{int x,y,val;P(int _x=0,int _y=0,int _v=0){  x=_x,y=_y,val=_v;    }
}p[30];int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
inline int bfs(int s,int n)
{while(!q.empty()) q.pop();for(int i=1;i<=n;i++) d[i]=INF;d[s]=0,q.push(s);while(!q.empty()){int x=q.front();q.pop();for(int i=h[x],y;i;i=e[i].pre)if(d[y=e[i].to]==INF) d[y]=d[x]+1,q.push(y);}return 0;
}
struct V{db x,y;V(db _x=0,db _y=0) { x=_x,y=_y; }
};
inline db cross(const V &a,const V &b) { return a.x*b.y+a.y*b.x; }
inline int sgn(db x) { return (x<0)?-1:(x>0); }
int main()
{int n,m,ans=0,sx=0,sy=0;int nc=0;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){static char s[MXA];scanf("%s",s+1);for(int j=1;j<=m;j++)if(s[j]=='S') sx=i,sy=j,a[i][j]=0;else if(s[j]=='#') a[i][j]=1;else if(s[j]=='.') a[i][j]=0;else if(s[j]=='B') a[i][j]=3;else p[s[j]-'1']=P(i,j,0),nc=max(nc,s[j]-'0'),a[i][j]=2;}for(int i=0;i<nc;i++) scanf("%d",&p[i].val);rep(i,1,n) rep(j,1,m) if(a[i][j]==3) p[nc++]=P(i,j,inf);int all=(1<<nc)-1,c=0;rep(i,1,n) rep(j,1,m) rep(s,0,all) id[i][j][s]=++c;rep(s,0,all) rep(i,1,n) rep(j,1,m) rep(k,0,3){if(a[i][j]) continue;int x=i+dx[k],y=j+dy[k],t=s;if(x<=0||x>n||y<=0||y>m||a[x][y]) continue;rep(q,0,nc-1){int px=p[q].x,py=p[q].y;V v1(px-i,j-py),v2(px-x,y-py),v3(1,sqrt3);int s1=sgn(cross(v3,v1)),s2=sgn(cross(v3,v2));if(s1!=s2&&py<=min(j,y)) t^=(1<<q);}add_edge(id[i][j][s],id[x][y][t]);
//      printf("(%d,%d,%d) -> (%d,%d,%d)\n",i,j,s,x,y,t);}bfs(id[sx][sy][0],c);for(int s=0,v;s<=all;ans=max(ans,v-d[id[sx][sy][s]]),s++)for(int i=v=0;i<nc;i++) if((s>>i)&1) v+=p[i].val;return !printf("%d\n",ans);
}

CF 221 C Circling Round Treasures - dp - 状压相关推荐

  1. CF 375C Circling Round Treasures [DP(spfa) 状压 射线法]

    C - Circling Round Treasures 题意: 在一个$n*m$的地图上,有一些障碍,还有a个宝箱和b个炸弹.你从(sx,sy)出发,走四连通的格子.你需要走一条闭合的路径,可以自交 ...

  2. Educational Codeforces Round 80 (Rated for Div. 2)SZU cf集训round2 C~E(dp,状压+二分,树状数组+逆向思维)

    C. Two Arrays 题目大意:就是给定两个整数n和m.计算数组对的数量(a,b),使得: 1 .两个阵列的长度都等于m: 2 .每个数组的每个元素都是1到n(包括1和n)之间的整数: 从1到m ...

  3. 状压搜索 Circling Round Treasures:CodeForces - 375C

    题目:Circling Round Treasures:CodeForces - 375C 题意: 给你一个N*M的地图(N,M<=20),地图上'#'表示障碍物,'B'表示炸弹,数字表示宝藏( ...

  4. 【BZOJ】1076 [SCOI2008]奖励关 期望DP+状压DP

    [题意]n种宝物,k关游戏,每关游戏给出一种宝物,可捡可不捡.每种宝物有一个价值(有负数).每个宝物有前提宝物列表,必须在前面的关卡取得列表宝物才能捡起这个宝物,求期望收益.k<=100,n&l ...

  5. 【CF375C】Circling Round Treasures

    Portal --> CF375C Solution 一个有趣的事情:题目中有很大的篇幅在介绍如何判断一个位置在不在所围的多边形中 那么..给了方法当然就是要用啊 ​ 首先是不能包含\('B'\ ...

  6. 【BZOJ 4565】 [Haoi2016]字符合并 区间dp+状压

    考试的时候由于总是搞这道题导致爆零~~~~~(神™倒序难度.....) 考试的时候想着想着想用状压,但是觉得不行又想用区间dp,然而正解是状压着搞区间,这充分说明了一件事,状压不是只是一种dp而是一种 ...

  7. #3864. Hero meet devil dp套dp + 状压 + 状态机

    传送门 文章目录 题意: 思路: 题意: 给你一个只包含ACGTACGTACGT的串sss,再给你一个mmm,第iii行输出有多少个长度为mmm且只包含ACGTACGTACGT的串与sss的lcslc ...

  8. [转]状态压缩dp(状压dp)

    状态压缩动态规划(简称状压dp)是另一类非常典型的动态规划,通常使用在NP问题的小规模求解中,虽然是指数级别的复杂度,但速度比搜索快,其思想非常值得借鉴. 为了更好的理解状压dp,首先介绍位运算相关的 ...

  9. 【CF375C】Circling Round Treasures【XSY1176】大包子环绕宝藏【状压dp】

    注意到题目中有这一句话: 注意路线可以自交.为了确定一个格子是否在这条路线里面,请使用以下算法判断: 1.假设该点的坐标为需要判断的点为 p(i,j) ,该点不在路线上 2.从该点往任意方向作一条射线 ...

最新文章

  1. 如何搭建亿级社交信息分享社交平台架构
  2. Android事件的响应,Android 开发事件响应之基于监听的事件响应
  3. Visual C++——《可视化编程技术》实验报告——MFC编程
  4. bugku ——加密 做题记录
  5. 专科程序员吐槽:学历是硬伤!问:想进大厂试试必须学历够格么?
  6. Web前端 性能优化
  7. C++还是Java常常无法想起数组
  8. Codeforces 776D The Door Problem
  9. 公众号点击图片变成另一张_公众号互动内容:小众潮流or下一个风口?| 新榜观察...
  10. 网页防篡改测试报告(2008版)
  11. Android高级控件(一)——ListView绑定CheckBox实现全选,添加和删除等功能
  12. Javascript:ES6语法简述
  13. PolyCode编译(Linux)
  14. Freyja2版本对分库分表的处理方式
  15. 【JZOJ5336】【NOIP2017提高A组模拟8.24】提米树
  16. 解决 SysFader:iexplore.exe应用程序错误
  17. matlab图像取样和量化,一文看懂数字图像的取样和量化
  18. Photoshop基础学习目录
  19. 【疑难杂症爆破委员会】UEFI Linux、Windows双系统,丢失Windows的efi文件导致找不到启动项(恢复Windows的efi文件)
  20. GA(遗传算法) 解决TSP问题 Python实现

热门文章

  1. 全球最流行12款浏览器
  2. 修复 rk3288 android9 的一些问题
  3. 学校计算机室应该配备哪种灭火器,学校教学楼应配备哪种灭火器
  4. gt9xx.c和gt9xx.h文件分析
  5. 华硕 内存条 不同步_千元级的RGB台式内存条——让你的主机流光溢彩
  6. JDWP exit error AGENT_ERROR_TRANSPORT_INIT(197): No transports initialize
  7. 华为路由器显示网络未连接到服务器,华为路由器Q1连接没有网络该怎么办
  8. 机器人主要有哪几部分组成?
  9. echarts 修改地图经纬度
  10. Excel 创建多级列表