码迷,mamicode.com
首页 > 其他好文 > 详细

【ACM】动态规划?剪枝?贪心?jobdu 1082

时间:2015-08-25 20:57:53      阅读:731      评论:0      收藏:0      [点我收藏+]

标签:

题目描述:

    使用代理服务器能够在一定程度上隐藏客户端信息,从而保护用户在互联网上的隐私。我们知道n个代理服务器的IP地址,现在要用它们去访问m个服务器。这 m 个服务器的 IP 地址和访问顺序也已经给出。系统在同一时刻只能使用一个代理服务器,并要求不能用代理服务器去访问和它 IP地址相同的服务器(不然客户端信息很有可能就会被泄露)。在这样的条件下,找到一种使用代理服务器的方案,使得代理服务器切换的次数尽可能得少。

输入:

    每个测试数据包括 n + m + 2 行。
    第 1 行只包含一个整数 n,表示代理服务器的个数。
    第 2行至第n + 1行每行是一个字符串,表示代理服务器的 IP地址。这n个 IP地址两两不相同。
    第 n + 2 行只包含一个整数 m,表示要访问的服务器的个数。
    第 n + 3 行至第 n + m + 2 行每行是一个字符串,表示要访问的服务器的 IP 地址,按照访问的顺序给出。
    每个字符串都是合法的IP地址,形式为“xxx.yyy.zzz.www”,其中任何一部分均是0–255之间的整数。输入数据的任何一行都不包含空格字符。

     其中,1<=n<=1000,1<=m<=5000。

输出:

    可能有多组测试数据,对于每组输入数据, 输出数据只有一行,包含一个整数s,表示按照要求访问服务器的过程中切换代理服务器的最少次数。第一次使用的代理服务器不计入切换次数中。若没有符合要求的安排方式,则输出-1。

样例输入:
3
166.111.4.100
162.105.131.113
202.112.128.69
6
72.14.235.104
166.111.4.100
207.46.19.190
202.112.128.69
162.105.131.113
118.214.226.52
样例输出:
1
来源:
2009年清华大学计算机研究生机试真题
解析:
 
拿到这题的第一时间的分析是将其转化成这样一个问题,其他情况暂不考虑,变成了一个“机器猫抓肥老鼠”的游戏:
 
有一只非常懒的老鼠,在一个有很多洞口的房子里,一只机器猫想抓这只老鼠,但是老鼠拥有洞口之间瞬间转移的能力;而机器猫是程序控制的,只要程序完了老鼠没被抓就成功了,问老鼠最少转移多少次。
 
作为老鼠来考虑,就是一直懒下去,直到猫来抓才转移,但是转移的这么多洞口应该往哪儿去呢?
 
假设平行宇宙学说是成立的(脑洞开太大有木有!),我们有一个数组node来存储,如果老鼠在当前i洞口,老鼠最少转移了多少次。
 
怎么求呢?如果猫刚刚来到了这个洞口,下一次猫离开之后,这个洞口访问的最少次数,一定是从上一次猫抓时访问次数最少的洞口来到这个洞口,次数也就是上一次的访问次数最少加1,其余的保持不变。
 
既然数组存储的一定是最少的,那么到机器猫程序最后执行晚时,数组中的最小值则是我们要求解的值了。
 
这里也用到了map string这一对黄金搭档(最近好久没见这个广告kk)~
 
PS 看了大多数小伙伴的解法都是使用贪心法。思路选择服务器列表中最晚出现的一个(假设位置为p)作为服务器,即当从任务列表0位置遍历到p时,要发生一次切换,然后选择服务器列表中除当前服务器外最晚出现的一个作为新的服务器。如此循环直到遍历完整个任务列表。其实这个思路还是比较容易 想起来的,有点像操作系统中学调度的感觉。开始写这一篇时还没弄清楚我的思路到底是什么大类,现在看来应该是动态规划没错了~
对了,如果能发现贪心的话肯定是用贪心最省事了!
 
#include <stdio.h>
#include <string.h>
#include <map>
#include <string>
using namespace std;
map<string,int> M;
int nodenum;
int servernum;
int node[1001];
int nodehash[1001];
int server[5001];
char temp[16];
string addr;
int serverid;
int mintime;
int minvalue()
{
    int mintemp = 0x7fffffff;
    for(int i = 0; i<nodenum; i++)
    {
        if(node[i]<mintemp&&node[i]!=-1)
            mintemp = node[i];
    }
    return mintemp;
}
int main()
{
#ifdef LOCAL
    freopen("data.in","r",stdin);
#endif // LOCAL
    //Format input here
    while(scanf("%d",&nodenum)!=EOF)
    {
        //Do something here
        M.clear();
        memset(node,0,sizeof(int)*1001);
        memset(nodehash,0,sizeof(int)*1001);
        memset(server,0,sizeof(int)*5001);
        mintime = 0x7fffffff;
        serverid=0;
 
        for(int i=0; i<nodenum; i++)
        {
            scanf("%s",temp);
            addr = temp;
            M[addr] = i;
        }
        scanf("%d",&servernum);
        for(int i=0; i<servernum; i++)
        {
            scanf("%s",temp);
            addr = temp;
            if(M.find(addr)==M.end())
                continue;
            else
            {
                server[serverid++]=M[addr];
                nodehash[M[addr]]=1;
            }
        }
 
        for(int i=0; i<nodenum; i++)
        {
            if(nodehash[i]==0)
            {
                mintime = 0;
                break;
            }
        }
 
        if(mintime ==0)
        {
            printf("0\n");
            continue;
        }
        node[server[0]]=-1;
        for(int i = 1; i<serverid; i++)
        {
            for(int j=0; j<nodenum; j++)
            {
                if(node[j]==-1)
                    node[j]=minvalue()+1;
            }
            node[server[i]]=-1;
            //for(int k=0; k<nodenum; k++)
            //    printf("%d  ",node[k]);
            //printf("\n");
        }
        int mm = minvalue();
        if(mm!=0x7fffffff)
            printf("%d\n",minvalue());
        else
            printf("-1\n");
    }
    return 0;
}
 
/**************************************************************
    Problem: 1082
    User: windcarp
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1084 kb
****************************************************************/

【ACM】动态规划?剪枝?贪心?jobdu 1082

标签:

原文地址:http://www.cnblogs.com/windcarp/p/4758323.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!