CF 375C Circling Round Treasures [DP(spfa) 状压 射线法]
2017-03-04 19:29
399 查看
C - Circling Round Treasures
题意:
在一个$n*m$的地图上,有一些障碍,还有a个宝箱和b个炸弹。你从(sx,sy)出发,走四连通的格子。你需要走一条闭合的路径,可以自交,且围出来的复杂多边形内不能包含任何炸弹。
你围出来的复杂多边形中包含的宝箱的价值和减去步数就是你的收益。
求最大收益。$n,m \le 20,a + b \le 8$
太坑了课件上的题意有问题一开始没说步数...
后来改上然后$inq[][][]$最后没从$2$改成$S$然后我就看着玄学的$inq$好长时间
和上题一样,只不过从一个点变成多个点,状压一下就好了、
更新答案的时候枚举状态计算是否有炸弹和价值和
题意:
在一个$n*m$的地图上,有一些障碍,还有a个宝箱和b个炸弹。你从(sx,sy)出发,走四连通的格子。你需要走一条闭合的路径,可以自交,且围出来的复杂多边形内不能包含任何炸弹。
你围出来的复杂多边形中包含的宝箱的价值和减去步数就是你的收益。
求最大收益。$n,m \le 20,a + b \le 8$
太坑了课件上的题意有问题一开始没说步数...
后来改上然后$inq[][][]$最后没从$2$改成$S$然后我就看着玄学的$inq$好长时间
和上题一样,只不过从一个点变成多个点,状压一下就好了、
更新答案的时候枚举状态计算是否有炸弹和价值和
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int N=22,S=1<<8,M=N*N*S+5,INF=1e9; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int n,m,g ,sx,sy,val ; struct Object{ int x,y,id; Object(int a=0,int b=0,int c=0):x(a),y(b),id(c){} bool operator <(const Object &r)const{return id<r.id;} }a ; int p,t; int dx[4]={1,-1,0, 0}, dy[4]={0, 0,1,-1}; char s ; int d [S]; struct Grid{ int x,y,s; Grid(int a=0,int b=0,int c=0):x(a),y(b),s(c){} }q[M]; int head,tail,inq [S]; inline void lop(int &x){if(x==M) x=1;} inline bool isInter(int a,int b,int x1,int y1,int x2,int y2){//1-->2 isInter (a,b)--right--> if(x1<a&&x2==a&&y2>b) return 1; if(x2<a&&x1==a&&y1>b) return 1; return 0; } int HandleInter(Grid u,Grid t){ int s=u.s; for(int i=0;i<8;i++) s^= isInter(a[i].x , a[i].y , u.x , u.y , t.x , t.y)<<i; return s; } void spfa(){ d[sx][sy][0]=0; head=tail=1; q[tail++]=Grid(sx,sy,0);inq[sx][sy][0]=1; while(head!=tail){ Grid u=q[head++];lop(head); int x=u.x,y=u.y,s=u.s;//printf("\nnow %d %d %d\n",x,y,p); inq[x][y][s]=0; for(int i=0;i<4;i++){ int nx=x+dx[i],ny=y+dy[i]; if(nx<1||nx>m||ny<1||ny>n||g[nx][ny]) continue; Grid t(nx,ny); int ns=t.s=HandleInter(u,t);//printf("lok %d %d %d\n",nx,ny,np); if(d[nx][ny][ns]>d[x][y][s]+1){//srintf("new %d %d %d\n",nx,ny,ns); d[nx][ny][ns]=d[x][y][s]+1; if(!inq[nx][ny][ns]) q[tail++]=t,lop(tail),inq[nx][ny][ns]=1; } } } int ans=0; for(int i=0;i<S;i++) if(d[sx][sy][i]<INF){ int _=0,bomb=0; for(int j=0;j<8;j++) if(i&(1<<j)){ if(a[j].id==10) {bomb=1;continue;} else _+=val[j]; } if(bomb) continue; ans=max(ans,_-d[sx][sy][i]); } printf("%d",ans); } int main(){ //freopen("in","r",stdin); m=read();n=read(); memset(d,127,sizeof(d)); for(int i=1;i<=m;i++){ scanf("%s",s+1); for(int j=1;j<=n;j++){ g[i][j]=(s[j]!='.'); if(s[j]=='S') g[i][j]=0,sx=i,sy=j; else if(s[j]=='B') a[p++]=Object(i,j,10); else if(s[j]>='0'&&s[j]<='9') a[p++]=Object(i,j,s[j]-'0'-1),t++; } } sort(a,a+p); for(int i=0;i<t;i++) val[i]=read(); spfa(); }
相关文章推荐
- CF 375C Circling Round Treasures(状态压缩+bfs)
- Codeforces 375C Circling Round Treasures - 最短路 - 射线法 - 位运算
- POJ 3182 The Grove [DP(spfa) 射线法]
- 状压搜索 Circling Round Treasures:CodeForces - 375C
- cf 11D A Simple Task(状压DP)
- cf 401D. Roman and Numbers 数位dp,状压
- 20160930的考试,noip模拟】SPFA,LIS,状压dp
- BZOJ 2595: [Wc2008]游览计划 [DP 状压 斯坦纳树 spfa]【学习笔记】
- hdu 4568 Hunter(spfa预处理 + 状压dp)
- CF855E,状压数位DP
- [CF 417D]Cunning Gena:状压DP
- hdu 4568 Hunter(spfa预处理 + 状压dp)
- HDU 4568 (SPFA 状压DP)
- ZOJ2923 Calculate Roads(SPFA上的dp)
- [BZOJ 1003] 物流运输 SPFA+DP
- poj1185(状压dp)
- 【DP】 cf 590D Top Secret Task
- zoj3471(状压dp)
- poj 3254 Corn Fields (状压dp)
- 【DP】 cf 486D