hdu 5067 网络赛 状态压缩 或dfs

题意是给你n*m的方格 里面有最多10个格子有数  问你最少走多少步能将所有的数字移到左上角    能无限装下数字

这里介绍两种做法  dfs和状态压缩dp

1   dfs

由于每个数字之间是一定可以到达的  所有只用考虑走有数字的情况   最多10!种情况  找到做小的就行   果断的深搜       注意下优化

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;

struct node
{
    int x,y;
}leap[20];
int abs(int a)
{
    return a<0?-a:a;
}
int map[55][55],k,Min,visit[20];
int dfs(int step,int num,int x,int y)
{
    int i;
    if(step>Min) return 0;
    if(num==k)
    {
        if(step+x-1+y-1<Min)
        Min=step+x-1+y-1;
        return 0;
    }
    for(i=1;i<=k;i++)
    {
        if(visit[i]) continue;
        visit[i]=1;
        dfs(step+abs(leap[i].x-x)+abs(leap[i].y-y),num+1,leap[i].x,leap[i].y);
        visit[i]=0;
    }
    return 0;
}
int main()
{
    int i,j,n,m;
    while(~scanf("%d%d",&n,&m))
    {
        k=0;
        for(i=1;i<=n;i++)
        for(j=1;j<=m;j++)
        {
            scanf("%d",&map[i][j]);
            if(map[i][j])
            {
                leap[++k].x=i;
                leap[k].y=j;
            }
        }
        Min=99999999;
        memset(visit,0,sizeof(visit));
        dfs(0,0,1,1);
        if(k==0) printf("0\n");
        else
        printf("%d\n",Min);
    }
    return 0;
}

2 状态压缩dp

这里的点只针对有数字的点

共10种状态       dp【i】【j】表示状态i里走到j这个点的最少步数     dis表示每个点之间所需要的步数

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define INF 0x3f3f3f3f

int min(int a,int b)
{
    return a<b?a:b;
}
struct node
{
    int x,y;
}leap[15];
int abs(int a)
{
    return a<0?-a:a;
}
int cont(int a, int b)
{
    return abs(leap[a].x-leap[b].x)+abs(leap[a].y-leap[b].y);
}
int dp[5000][15];
int main()
{
    int i,j,n,m,a;
    while(~scanf("%d%d",&n,&m))
    {
        int k=0;
        for(i=1;i<=n;i++)
        for(j=1;j<=m;j++)
        {
            scanf("%d",&a);
            if(a)
            {
                leap[++k].x=i;
                leap[k].y=j;
            }
        }
        leap[0].x=leap[0].y=1;
        int state=1<<(k+1);
        memset(dp,INF,sizeof(dp));
        int dis[15][15];
        for(i=0;i<=k;i++)
        for(j=i;j<=k;j++)
        dis[i][j]=dis[j][i]=cont(i,j);
        dp[1][0]=0;
        for(i=1;i<state;i++)
        {
            for(j=0;j<=k;j++)
            {
                if(dp[i][j]==INF) continue;
                for(int z=0;z<=k;z++)
                {
                    if(i&(1<<z)) continue;
                    dp[i|(1<<z)][z]=min(dp[i|(1<<z)][z],dp[i][j]+dis[j][z]);
                }
            }
        }
        int Min=9999999;
        for(i=0;i<=k;i++)
        if(dp[state-1][i]+dis[i][0]<Min) Min=dp[state-1][i]+dis[i][0];
        printf("%d\n",Min);
    }
    return 0;
}
时间: 2024-11-13 06:07:46

hdu 5067 网络赛 状态压缩 或dfs的相关文章

hdu 4352 数位dp + 状态压缩

XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2265    Accepted Submission(s): 927 Problem Description #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then careful

hdu 4778 Rabbit Kingdom(状态压缩)

题目链接:hdu 4778 Rabbit Kingdom 题目大意:Alice和Bob玩游戏,有一个炉子,可以将S个相同颜色的宝石换成一个魔法石,现在有B个包,每个包里有若干个宝石,给出宝石的颜色.现在由Alice开始,两人轮流选取一个包的宝石放入炉中,每当获得一个魔法石时,可以额外获得一次机会再选一个包放入.两人均按照自己的最优策略,问说最后Alice的魔法石-Bob的魔法石是多少. 解题思路:状态压缩,221,对于每次移动到下一个状态,如果获得的魔法石g非零,则说明下一个状态还是自己在取,则

hdu 3217 Health(状态压缩DP)

Health Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 527    Accepted Submission(s): 145 Problem Description Unfortunately YY gets ill, but he does not want to go to hospital. His girlfriend LM

HDU 1885 Key Task 状态压缩+搜索

点击打开链接 Key Task Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1176    Accepted Submission(s): 462 Problem Description The Czech Technical University is rather old - you already know that it c

hdu 4856 Tunnels(bfs+状态压缩)

题目链接:hdu 4856 Tunnels 题目大意:给定一张图,图上有M个管道,管道给定入口和出口,单向,现在有人想要体验下这M个管道,问最短需要移动的距离,起点未定. 解题思路:首先用bfs处理出两两管道之间移动的距离,然后后用状态压缩求出最短代价,dp[i][j],i表示的已经走过的管道,j是当前所在的管道. #include <cstdio> #include <cstring> #include <queue> #include <algorithm&g

HDU 1557 权利指数 状态压缩 暴力

HDU 1557 权利指数 状态压缩 暴力 ACM 题目地址:HDU 1557 权利指数 题意: 中文题,不解释. 分析: 枚举所有集合,计算集合中的和,判断集合里面的团体是否为关键团队. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * File: 1557.cpp * Create Date: 2014-06-28 14:47:58 * Descripton: brute force/ set */ #include <cstdio&g

hdu 4057 AC自动机+状态压缩dp

http://acm.hdu.edu.cn/showproblem.php?pid=4057 Problem Description Dr. X is a biologist, who likes rabbits very much and can do everything for them. 2012 is coming, and Dr. X wants to take some rabbits to Noah's Ark, or there are no rabbits any more.

hdu 6444 网络赛 Neko&#39;s loop(单调队列 + 裴蜀定理)题解

题意:有编号为0~n-1的n个游戏,每个活动都有一个价值(可为负),给你m,s和k,你可以从任意一个编号开始玩,但是下一个游戏必须是编号为(i + k)%n的游戏,你最多能玩m次游戏,问你如果最后你手里要有s的价值,那么你至少一开始要有多少价值. 思路:由裴蜀定理可以知道,如果有n个值首尾相连,间隔为k地走,那么最后会有一个循环节,这样的循环节一共有gcd(n, k)个,每个循环节长度n / gcd(n, k)个.所以我们只要找出所有循环节,并且把每个循环节的最大价值算出来就行了.对于每个循环节

hdu 4628 Pieces(状态压缩+记忆化搜索)

Pieces Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1811    Accepted Submission(s): 932 Problem Description You heart broke into pieces.My string broke into pieces.But you will recover one