hdu 3681 二分枚举答案+dp判断答案

来源:互联网 发布:淘宝最火的女装店铺 编辑:程序博客网 时间:2024/06/07 05:08

一开始以为是搜索,然后不知道怎么办了。。。那么多状态。。。因为那个夏天的风的分类是在搜索里面,最后看了解题报说是dp。。。。。

思路:

先用BFS搜出Y与G,G与F,F与Y的距离,然后就用二分枚举答案,用dp来判断答案是否能行。

dp就是一个TSP问题。。。。

我写的时候有一个地方要注意,就是dp判断里面结束的判断。。。一开始用的是〉~~的。。最后发现这样不行。。。。因为如果一个power位为1的话就能满足这个状态了。。。最后构造了一个变量judge来判断。。。

AC代码如下:

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cstdlib>#include <queue>using namespace std;typedef struct{int x, y;int step;}Point;int dp[16][1<<16];char maps[20][20];Point energy[16], switchs[16], point[20], start;int num_energy, num_switchs, num_sum;int N, M;int dis[20][20];int moves[][2] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };int judge;int calc_dis( Point first, Point last ){queue<Point> q;bool mark[20][20];memset( mark, false, sizeof( mark ) );first.step = 0;q.push( first );mark[first.x][first.y] = true;while( !q.empty() ){Point n = q.front();q.pop();if( n.x == last.x && n.y == last.y ){return n.step;}for( int i = 0; i < 4; i++ ){Point temp;temp.x = n.x + moves[i][0];temp.y = n.y + moves[i][1];temp.step = n.step + 1;if( temp.x < 0 || temp.x >= N || temp.y < 0 || temp.y >= M || maps[temp.x][temp.y] == 'D' ){continue;}if( !mark[temp.x][temp.y] ){q.push( temp );mark[temp.x][temp.y] = true;}}}return -1;}bool check( int size ){memset( dp, -1, sizeof( dp ) );dp[0][1] = size;for( int i = 1; i <= ( 1 << ( num_sum + 1 ) ) - 1; i++ ){for( int j = 0; j <= num_sum; j++ ){if( dp[j][i] != -1 ){if( ( i & judge ) == judge ){//注意结束的判断,以及judge的构造return true;}for( int k = 1; k <= num_sum; k++ ){if( !( i & ( 1 << k ) ) && k != j ){if( k > num_switchs && dis[j][k] <= dp[j][i] && dis[j][k] != -1 ){dp[k][i|(1<<k)] = size;}else if( k <= num_switchs && dis[j][k] <= dp[j][i] && dis[j][k] != -1 ){if( dp[k][i|(1<<k)] == -1 ){dp[k][i|(1<<k)] = dp[j][i] - dis[j][k];}else{dp[k][i|(1<<k)] = max( dp[k][i|(1<<k)], dp[j][i] - dis[j][k] );}}}}}}}return false;}int main(){while( scanf( "%d%d", &N, &M ) && N && M ){memset( maps, 0, sizeof( maps ) );num_energy = 0;num_switchs = 0;for( int i = 0; i < N; i++ ){scanf( "%s", maps[i] );for( int j = 0; j < M; j++ ){if( maps[i][j] == 'F' ){start.x = i;start.y = j;}else if( maps[i][j] == 'Y' ){switchs[num_switchs].x = i;switchs[num_switchs++].y = j;}else if( maps[i][j] == 'G' ){energy[num_energy].x = i;energy[num_energy++].y = j;}}}num_sum = num_energy + num_switchs;for( int i = 1; i <= num_sum; i++ ){if( i <= num_switchs ){point[i] = switchs[i-1];}else{point[i] = energy[i-num_switchs-1];}}point[0] = start;judge = 0;//注意judge的构造for( int i = 0; i <= num_switchs; i++ ){judge |= ( 1 << i );}for( int i = 0; i <= num_sum; i++ ){for( int j = i + 1; j <= num_sum; j++ ){dis[i][j] = dis[j][i] = calc_dis( point[i], point[j] );}}int ans, l, r, mid;ans = 260;l = 0;r = ans;while( l <= r ){mid = ( l + r ) / 2;if( check( mid ) ){ans = min( mid, ans );r = mid - 1;}else{l = mid + 1;}}if( ans == 260 ){cout << -1 << endl;}else{cout << ans <<endl;}}return 0;}


 

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 安逍遥模拟器运行一段时间卡怎么办 pos机微信支付签到失败怎么办 逆水寒fps过低怎么办 电脑卡怎么办怎么清理磁盘 苹果手机设置找不到了怎么办 苹果手机自动拨出电话怎么办 机械键盘灯坏了怎么办 黄金塔花叶子卷怎么办 办的宽带不用了怎么办 取卵后3天还出血怎么办 取卵后腹水怎么办9天了 取卵后第三天肚子涨第天移植怎么办 取卵移植后肚子涨怎么办 没有成熟的卵泡不排卵怎么办 产后9年妊娠纹痒怎么办 手机屏幕锁了忘记密码怎么办 电脑被黑客锁屏怎么办 r9解锁密码忘了怎么办 oppor9开机密码忘了怎么办 vivo手机忘记解锁图案怎么办 oppor9s解锁图案忘了怎么办 oppor9图案解锁忘记了怎么办 oppor9解锁图案忘了怎么办 oppor9s锁屏密码忘了怎么办 oppor9s忘记锁屏图案怎么办 oppor9忘记锁屏图案怎么办 电脑锁屏卡住了怎么办 dell电脑密码忘了怎么办 dell电脑密码忘记了怎么办 手机锁屏为什么打不开怎么办 手机图形解锁忘记了怎么办 华硕电脑锁屏了怎么办 5s忘记解锁密码怎么办 苹果手机密码忘记了怎么办 苹果手机iphone已停用怎么办 手机被停用怎么办不用电脑 激活锁是别人的怎么办 6s开机密码忘了怎么办 苹果手机忘记解锁密码怎么办 忘记苹果触控id怎么办 苹果6app被锁了怎么办