Problem Statement

Bob is going to create a graph with N nodes. The graph will be constructed in two steps. First, Bob will take N isolated vertices, label them 1 through N and color each of them using one of K colors.
Then, Bob will add some directed edges to the graph. For each i between 2 and N, inclusive, Bob may choose a single value j < i such that the nodes i and j have different colors. If he does, he will add the edge from i to j to his graph. Note
that Bob may choose not to add any edge from node i, even if there are some valid choices of j.

Two graphs are considered the same if they have the same node colors and the same set of edges.

You are given the ints N and K. Compute and return the number of different graphs Bob may construct, modulo 1,000,000,007.

Definition

  • ClassColorfulLineGraphsDiv2
  • MethodcountWays
  • Parametersint , int
  • Returnsint
  • Method signatureint countWays(int N, int K)
(be sure your method is public)

Limits

  • Time limit (s)2.000
  • Memory limit (MB)256

Constraints

  • N will be between 1 and 100, inclusive.
  • K will be between 1 and 3, inclusive.

Test cases

    • N3
    • K2

    Returns24

    The 24 different graphs are shown below. In each picture, the vertices have labels 1, 2, 3 from the left to the right.

    • N15
    • K2

    Returns789741546

    • N100
    • K1

    Returns1

    • N1
    • K3

    Returns3

    • N100
    • K3

    Returns

    492594064

  1. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    There can be at most 3 colors. So how about we solve for 3 colors, then we can adapt the solution for fewer number of colors with small tweaks.

    The problem statement describes the decision as first choosing colors and then creating the edges. But the actual rules for counting the unique setups combines the two together. Let's try to make the decision about picking a color AND an edge for each vertex.

    Imagine we've already picked colors and edges for the first i nodes,
    let's decide the i-th
    node. We can pick one of 3 colors:

    • Pick color A. Now we have to decide the edge. We can choose to connect vertex i to
      any of the previous vertices as long as they have a different color. Since this is a counting problem, let's keep in mind the counts for each color (assume 3 colors) : a, b and c.
      We cannot connect to color a,
      so there are b+c vertices
      we can connect this vertex to. There is an additional option: Don't connect the vertex at all. This gives b+c+1 options.
      Note that later vertices don't need to know what edge we picked, only the color.
    • If we pick color B: There are 1+a+c options.
    • 1+a+b options
      in case color C is picked.

    The idea is that we can just increment the count of the respective color and move on to the next i.
    Also note that i=a+b+c,
    because there were i vertices
    so the sum of all colors must be i.
    This helps us do a dynamic programming solution. Let's name f(a,b,c) to
    the number of ways to pick colors and edges for vertices starting from i=a+b+c onwards,
    assuming there were a, b and c vertices
    of each color among the first i vertices.

    • Base case: a+b+c=N.
      This means that we have already made a decision for all the vertices and there is nothing else to do. One way to do nothing: The result is 1.
    • Else there are 3 options:
      • We can pick color A.
        This means (1+b+c) options
        for the edge. The number of A vertices
        is incremented. Between picking the edge and picking the next colors/edges we have two independent decisions, so we multiply: (1+b+c)⋅f(a+1,b,c).
      • Or pick color B: (1+a+c)⋅f(a,b+1,c).
      • Or C: (1+a+b)⋅f(a,b,c+1).

      The addition of these 3 values is the result for f(a,b,c).

    Fewer colors

    When there are two colors, we can just disable the part where we pick color C.
    The state can still be (a,b,c),
    but c will
    always be 0.

    When there is one color, we can just return the number of graphs of size N that
    follow this rule OR we can do the same trick as for K=2 and
    just disable the part where we decide to use color B and C.

    Code

    The idea with that recurrence relation is that it is acyclic and the number of states is not very large O(n3).
    We can implement the recurrence using memoization or iteratively (dynamic programming) to guarantee O(n3) run
    time.

    const int MOD = 1000000007;
    
    int dp[101][101][101];
    
    int N, K;
    
    int f(int a, int b, int c)
    {
    int & res = dp[a][b][c];
    if (res == -1) {
    if (a + b + c == N) {
    // the end
    res = 1;
    } else {
    res = 0;
    long p, q;
    // color vertex with color a
    p = 1 + b + c;
    q = f(a + 1, b, c);
    res += (int)( (p * q) % MOD );
    res %= MOD; // color vertex with color b
    if (K >= 2) {
    p = 1 + a + c;
    q = f(a, b + 1, c);
    res += (int)( (p * q) % MOD );
    res %= MOD;
    } // color vertex with color c
    if (K >= 3) {
    p = 1 + a + b;
    q = f(a, b, c + 1);
    res += (int)( (p * q) % MOD );
    res %= MOD;
    }
    }
    }
    return res;
    } int countWays(int N, int K)
    {
    this->N = N;
    this->K = K;
    memset(dp, -1, sizeof(dp));
    return f(0,0,0);
    }

DP SRM 661 Div2 Hard: ColorfulLineGraphsDiv2的更多相关文章

  1. TopCoder SRM 301 Div2 Problem 1000 CorrectingParenthesization(区间DP)

    题意  给定一个长度为偶数的字符串.这个字符串由三种括号组成. 现在要把这个字符串修改为一个符合括号完全匹配的字符串,改变一个括号的代价为$1$,求最小总代价. 区间DP.令$dp[i][j]$为把子 ...

  2. Topcoder Srm 673 Div2 1000 BearPermutations2

    \(>Topcoder \space Srm \space 673 \space Div2 \space 1000 \space BearPermutations2<\) 题目大意 : 对 ...

  3. Topcoder Srm 671 Div2 1000 BearDestroysDiv2

    \(>Topcoder \space Srm \space 671 \space Div2 \space 1000 \space BearDestroysDiv2<\) 题目大意 : 有一 ...

  4. SRM 657 DIV2

    -------一直想打SRM,但是感觉Topcoder用起来太麻烦了.题目还是英文,不过没什么事干还是来打一打好了.但是刚注册的号只能打DIV2,反正我这么弱也只适合DIV2了.. T1: 题目大意: ...

  5. Topcoder srm 632 div2

    脑洞太大,简单东西就是想复杂,活该一直DIV2; A:水,基本判断A[I]<=A[I-1],ANS++; B:不知道别人怎么做的,我的是100*N*N;没办法想的太多了,忘记是连续的数列 我们枚 ...

  6. SRM 628 DIV2

    250  想想就发现规律了. 500  暴力,括号匹配. 1000 给一个f数组,如果i存在,那么f[i]也得存在,问这样的集合有多少种. 先拓扑一下,dp[i] = mul(dp[son]+1)最后 ...

  7. Topcoder SRM 683 Div2 - C

    树形Dp的题,根据题意建树. DP[i][0] 表示以i为根节点的树的包含i的时候的所有状态点数的总和 Dp[i][1] 表示包含i结点的状态数目 对于一个子节点v Dp[i][0] = (Dp[v] ...

  8. 记第一次TopCoder, 练习SRM 583 div2 250

    今天第一次做topcoder,没有比赛,所以找的最新一期的SRM练习,做了第一道题. 题目大意是说 给一个数字字符串,任意交换两位,使数字变为最小,不能有前导0. 看到题目以后,先想到的找规律,发现要 ...

  9. SRM 595 DIV2 1000

    数位DP的感觉,但是跟模版不是一个套路的,看的题解,代码好理解,但是确实难想. #include <cstdio> #include <cstring> #include &l ...

随机推荐

  1. SHELL异常处理(转载)

    写SHELL好久了,经常被异常困扰,可竟然坚持了若干年没用过,回想以前服务过的公司,阿弥陀佛,罪过罪过.废话少说,希望此篇文章可以协助大家和我彻底结束SHELL脚本就是LINUX命令集合的初级阶段. ...

  2. [转]Android:异步处理之AsyncTask的应用(二)

    2014-11-07     既然UI老人家都这么忙了,我们这些开发者肯定不能不识趣的去添乱阻塞UI线程什么的,否则UI界面万一停止响应了呢——这不是招骂的节奏么?!所以我们知道用Handler+Th ...

  3. HDU 5301 Buildings 数学

    Buildings 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5301 Description Your current task is to m ...

  4. 普及向 ZKW线段树!

    啊,是否疲倦了现在的线段树 太弱,还递归! 那我们就欢乐的学习另外一种神奇的线段树吧!(雾 他叫做zkw线段树   这个数据结构灰常好写(虽然线段树本身也特别好写……) 速度快(貌似只在单点更新方面比 ...

  5. 如何使用DotNet 2.0中的应用程序配置 Settings.settings

    对于桌面应用程序,常常会需要记录一些用户配置信息,早期的做法一般是使用读写INI文件的办法.    对于.NET应用程序,并没有提供直接操作INI文件的类,需要调用Win32API,具体办法可以参考: ...

  6. Apache Thrift使用简介

    Apache Thrift 是 Facebook 实现的一种高效的.支持多种编程语言的远程服务调用的框架.和其它RPC框架相比,它主要具有如下连个特点: 高性能. 它采用的是二进制序列化,并且用的是长 ...

  7. DAC calibrates 4- to 20-mA output current

    Industrial controls make heavy use of 4- to 20-mA current loops to transmit process measurements bec ...

  8. 小程序setData工作原理理解图

    优化建议:1.频繁的去setData--我曾经用这个弄过动画效果,当然后来发现JS动画不适合小程序,CSS3动画才是王道2.每次setData都传递大量新数据--这个大量还真不好理解,暂时定为排行榜类 ...

  9. JavaScript面向对象编程指南(第2版)》读书笔记

    一.对象 1.1 获取属性值的方式 water = { down: false } console.log(water.down) // false console.log(water['down'] ...

  10. Netty框架

    Netty框架新版本号:3.0.2.GA,于2008年11月19日公布.Netty项目致力于提供一个异步的.事件驱动的网络应用框架和工具,用于高速开发可维护的.高性能的.高扩展性的server和cli ...