规律,模拟,贪心(Travelling Salesman Problem,HDU 5402)

来源:互联网 发布:centos 7 unmount 编辑:程序博客网 时间:2024/06/08 20:02

显然行列有一个是奇数就可以全部走完。这种情况直接模拟就好。

否则的话,一定会有一个格子走不到。

多试几种情况就可以发现这个规律。

证明的话:http://blog.csdn.net/queuelovestack/article/details/47756605

就是对整个棋盘进行黑白二染色,如果行列相加为偶数,就染成黑色,否则染成白色。我们的路径一定是黑白相间。

当行列皆为偶数的时候我们可以发现矛盾。

此时(1,1)是黑色,(n,m)也是黑色。因为路径黑白相间,所以经过的白色格子一定比黑色格子少一个。而整个棋盘中黑白格子的个数是相等的,所以至少有1个白色格子是走不到的。

比赛时不一定能想到严格证明,但若能发现规律,并且有一定把握也是可以的。

至于该如何模拟,看到了网上有很简单的办法,就是随便绕绕就绕过去了,我的模拟就麻烦很多了。

如果可以,尽量想出一些简单的模拟办法,当然能想到自己的办法是好事,但这可能会给编程带来一些麻烦。

希望自己在找到线索之后可以进一步地把它想清楚,从而找到更简单的规律,然后再开始编程。


代码

#include<stdio.h>#include<vector>using namespace std;const int maxn = 110;int n,m;int MAP[maxn][maxn];int mr,mc;vector<char>vec;int ans;int vis[maxn][maxn];void read(){    ans=0;    vec.clear();    mr=mc=0;    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)        {            vis[i][j]=0;            scanf("%d",&MAP[i][j]);            if(!(i==1&&j==1)&&!(i==n&&j==m)&&((i+j)&1)&&MAP[mr][mc]>MAP[i][j])            {                mr=i;                mc=j;            }        }}bool ok(int r,int c){    return 1<=r&&r<=n&&1<=c&&c<=m&&!(r==mr&&c==mc)&&!vis[r][c];}int change(int r,int c,int t){    if(t==0)    {        if(c==m) return 1;        for(int i=1;i<=n;i++)            if(ok(i,c+1)&&!vis[i][c+1]) return 0;        return 1;    }    if(t==1)    {        if(c==1) return n-r<=m-c?2:0;        for(int i=1;i<=n;i++)            if(ok(i,c-1)&&!vis[i][c-1]) return 1;        return n-r<=m-c?2:0;    }    if(t==2)    {        if(r==n) return 3;        for(int i=1;i<=m;i++)            if(ok(r+1,i)&&!vis[r+1][i]) return 2;        return 3;    }    if(t==3)    {        if(r==1) return n-r<m-c?2:0;;        for(int i=1;i<=m;i++)            if(ok(r-1,i)&&!vis[r-1][i]) return 3;        return n-r<m-c?2:0;    }    return 0;}void dfs(int r,int c,int t){    ans+=MAP[r][c];    vis[r][c]=1;    if(r==n&&c==m) return;    t=change(r,c,t);    if(t==0)    {        if(ok(r-1,c))        {            vec.push_back('U');            dfs(r-1,c,t);        }        else if(ok(r,c+1))        {            vec.push_back('R');            dfs(r,c+1,t);        }        else if(ok(r+1,c))        {            vec.push_back('D');            dfs(r+1,c,t);        }        return;    }    else if(t==1)    {        if(ok(r-1,c))        {            vec.push_back('U');            dfs(r-1,c,t);        }        else if(ok(r,c-1))        {            vec.push_back('L');            dfs(r,c-1,t);        }        else if(ok(r+1,c))        {            vec.push_back('D');            dfs(r+1,c,t);        }        return;    }    else if(t==2)    {        if(ok(r,c-1))        {            vec.push_back('L');            dfs(r,c-1,t);        }        else if(ok(r+1,c))        {            vec.push_back('D');            dfs(r+1,c,t);        }        else if(ok(r,c+1))        {            vec.push_back('R');            dfs(r,c+1,t);        }        return;    }    else if(t==3)    {        if(ok(r,c-1))        {            vec.push_back('L');            dfs(r,c-1,t);        }        else if(ok(r-1,c))        {            vec.push_back('U');            dfs(r-1,c,t);        }        else if(ok(r,c+1))        {            vec.push_back('R');            dfs(r,c+1,t);        }        return;    }}void handle(){    if(n>=m) dfs(1,1,0);    else dfs(1,1,2);}void solve(){    read();    if((n&1)==0&&(m&1)==0);    else mr=mc=0;    handle();    printf("%d\n",ans);    for(int i=0;i<(int)vec.size();i++)        printf("%c",vec[i]);    puts("");}int main(){    MAP[0][0]=10010;    while(~scanf("%d %d",&n,&m)) solve();    return 0;}


阅读全文
0 0
原创粉丝点击