• hust Dating With Girls


    http://acm.sdibt.edu.cn:8080/judge/contest/view.action?cid=573#problem/B

    题意:求最大权值和,起点为1,终点为权值最大的那个点(其权值为负,而且在负数里最大),这题同时要求在到达负最大的权值那个点之前不能经过其他负数的点,

              而且没经过一个点,就加上该点的wi,最后一个点也要加上|wi|

    分析:刚开始我是搜索,纯搜,毫无疑问超时~~~

             后来实在无法,搜了解题报告发现是记忆化搜索,不过自己敲出来一直wa,纠结了好久后才知道,原来在取可连通路径最大值那里错了

     记忆化搜索

    View Code
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    const int MN=110;
    const int INF=0x7fffffff;
    int map[MN][MN];
    int num[MN];
    int dp[MN];
    int n,m;
    int MIN;
    int ans;
    int e;
    
    int DFS(int cur)
    {
        if(dp[cur]>=0) return dp[cur];
        if(cur==e) return -MIN;
        if(num[cur]==-INF) return 0;
        int MAX=0;
        for(int i=1; i<=n; i++)
        {
            if(cur==i) continue;
            if(map[cur][i])
            {
                int tmp=DFS(i);
                if(tmp>0) MAX=max(MAX,num[cur]+tmp);
                //这里的tmp>0必须要有,因为当路径不可达的情况下
                //递归所返回的值是0,而num[cur]>0这样必定比MAX=0
                //大,而其i点本身不可达,又哪来的比较
            }
        }
        return dp[cur]=MAX;
    }
    
    int main()
    {
        int i,j,a,b;
        int flag;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            flag=false;
            memset(map,0,sizeof(map));
            memset(dp,-1,sizeof(dp));
            for(i=1; i<=m; i++)
            {
                scanf("%d%d",&a,&b);
                map[a][b]=1;
            }
            MIN=99999;
            num[1]=0;
            for(i=2; i<=n; i++)
            {
                scanf("%d",&num[i]);
                if(num[i]<0)
                {
                    flag=true;
                    if(MIN>num[i])
                    {
                        MIN=num[i];
                        e=i;
                    }
                }
            }
            for(i=2;i<=n;i++)
            {//将所有小于最大负数的点赋予无穷,不可达
                if(num[i]<0 && num[i]>MIN) num[i]=-INF;
            }
            ans=DFS(1);
            if(ans==0 || flag==false) printf("What is a fucking day!\n");
            else printf("%d\n",ans);
        }
        return 0;
    }

    BFS

    View Code
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    
    using namespace std;
    const int MN=110;
    const int INF=0x7fffffff;
    int map[MN][MN];
    int num[MN];
    int mmax[MN];
    int vis[MN];
    int n,m;
    int MIN;
    int e;
    
    int BFS(int e)
    {
        int i,j;
        memset(vis,0,sizeof(vis));
        memset(mmax,-1,sizeof(mmax));
        queue<int>Q;
        Q.push(1);
        vis[1]=0;
        mmax[1]=0;
        while(!Q.empty())
        {
            int head=Q.front();
            Q.pop();
            for(i=1; i<=n; i++)
            {
                if(map[head][i])
                {
                    if(num[i]>0)//这里加上vis==0是错的
                    {//因为vis的作用只是判断点是否进过队列
                        if(mmax[i]<mmax[head]+num[i])
                            mmax[i]=mmax[head]+num[i];
                    }
                    if(i==e)
                    {
                        if(mmax[i]<mmax[head]-num[i])
                            mmax[i]=mmax[head]-num[i];
                    }
                    if(num[i]>0 && vis[i]==0)
                    {
                        Q.push(i);
                        vis[i]=1;
                    }
                }
            }
            vis[head]=0;
        }
    }
    
    int main()
    {
        int i,j,a,b;
        int flag;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            flag=false;
            memset(map,0,sizeof(map));
            for(i=1; i<=m; i++)
            {
                scanf("%d%d",&a,&b);
                map[a][b]=1;
            }
            MIN=99999;
            num[1]=0;
            for(i=2; i<=n; i++)
            {
                scanf("%d",&num[i]);
                if(num[i]<0)
                {
                    flag=true;
                    if(MIN>num[i])
                    {
                        MIN=num[i];
                        e=i;
                    }
                }
            }
            for(i=2; i<=n; i++)
            {
                //将所有小于最大负数的点赋予无穷,不可达
                if(num[i]<0 && num[i]>MIN) num[i]=-INF;
            }
            BFS(e);
            if(mmax[e]>0) printf("%d\n",mmax[e]);
            else printf("What is a fucking day!\n");
        }
        return 0;
    }
  • 相关阅读:
    SQL练习题32:请你创建一个actor_name表,并且将actor表中的所有first_name以及last_name导入该表.
    SQL练习题31:对于表actor批量插入如下数据,如果数据已经存在,请忽略(不支持使用replace操作)
    SQL练习题30:对于表actor批量插入如下数据(不能有2条insert语句哦!)
    npm run dev 报错:missing script:dev
    [转]vue中“:”、“.”、“@”的意义
    Vue踩坑记录
    Vue指令:v-clock解决页面闪烁问题
    npm-安装模块时出现rollbackFailedOptional
    js中[]、{}、()的区别
    IDEA离线安装插件
  • 原文地址:https://www.cnblogs.com/zsboy/p/2952025.html
Copyright © 2020-2023  润新知