zoukankan      html  css  js  c++  java
  • Codeforces Round #179 (Div. 1) C. Greg and Friends(BFS 或者最短路)

    题目大意

    有 n(1n≤50) 个人,每个人的体重要么是 50,要么是 100。现在他们都在河岸的一边,有一条船,最大栽种量为 K(1≤k≤5000),问:把所有人从河这岸运送到河对岸去,最少需要划船多少次,以及共有多少种不同的坐船方案使得划船次数最少

    做法分析

    注意题目给出的条件,每个人的重量要么是 50 要么是 100,大家肯定都注意到这点了,怎么利用呢?这样考虑:

            在某个时刻,重量为 50 的人有多少个,重量为 100 的人有多少个,他们是在河的哪一边?

    想到这里,大家肯定就有思路了,可以 BFS,也可以求最短路,这样,最少需要划船的次数就求出来了

    至于多少种方案,BFS 或者求最短路的过程中再维护一个到达这个状态需要的划船的次数的信息即可

    我用的 BFS 做的

    参考代码

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <queue>
     5 
     6 using namespace std;
     7 
     8 typedef long long LL;
     9 const int N=56, MOD=1000000007;
    10 
    11 struct node
    12 {
    13     int x, y, id;
    14     node(int a, int b, int c):x(a), y(b), id(c) {}
    15 };
    16 queue <node> q;
    17 LL g[N][N][2];
    18 int f[N][N][2], n, m1, m2, k;
    19 int C[N][N];
    20 
    21 void BFS()
    22 {
    23     memset(f, -1, sizeof f);
    24     memset(g, 0, sizeof g);
    25     f[m1][m2][0]=0, g[m1][m2][0]=1;
    26     while(!q.empty()) q.pop();
    27     q.push(node(m1, m2, 0));
    28     while(!q.empty())
    29     {
    30         node cur=q.front();
    31         q.pop();
    32         int k1=cur.x, k2=cur.y, id=cur.id;
    33         for(int i=0; i<=k1; i++)
    34             for(int j=0; j<=k2; j++)
    35             {
    36                 if(i==0 && j==0) continue;
    37                 if(i*50+j*100>k) continue;
    38                 int x=m1-k1+i, y=m2-k2+j;
    39                 if(f[x][y][id^1]==-1)
    40                 {
    41                     f[x][y][id^1]=f[k1][k2][id]+1;
    42                     g[x][y][id^1]=(g[x][y][id^1]+C[k1][i]*g[k1][k2][id]%MOD*C[k2][j]%MOD)%MOD;
    43                     q.push(node(x, y, id^1));
    44                 }
    45                 else if(f[x][y][id^1]==f[k1][k2][id]+1)
    46                     g[x][y][id^1]=(g[x][y][id^1]+C[k1][i]*g[k1][k2][id]%MOD*C[k2][j]%MOD)%MOD;
    47             }
    48     }
    49 }
    50 
    51 int main()
    52 {
    53     memset(C, 0, sizeof C);
    54     for(int i=0; i<N; i++) C[i][0]=1;
    55     for(int i=1; i<N; i++)
    56         for(int j=1; j<=i; j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
    57 
    58     scanf("%d%d", &n, &k);
    59     m1=0, m2=0;
    60     for(int i=0, a; i<n; i++)
    61     {
    62         scanf("%d", &a);
    63         if(a==50) m1++;
    64         else m2++;
    65     }
    66     BFS();
    67     printf("%d\n%I64d\n", f[m1][m2][1], g[m1][m2][1]);
    68     return 0;
    69 }
    C. Greg and Friends

    题目链接 & AC通道

    Codeforces Round #179 (Div. 1) C. Greg and Friends

  • 相关阅读:
    Java 包装类的自动封箱与拆箱
    Java 基本类型的包装类
    Java日期时间练习三(闰年)
    导入包与模块
    模块_os模块
    Re模块练习题
    Re模块的方法补充
    Re模块的 三个方法
    基础纹理
    ruby 的数组操作
  • 原文地址:https://www.cnblogs.com/zhj5chengfeng/p/3076983.html
Copyright © 2011-2022 走看看