zoukankan      html  css  js  c++  java
  • SRM532 D1 L2

    很有趣的一道题目,套了两个动态规划。

    Promblem Statement

    题目大意是有N个顶点,需要连M条无向边,要求两个顶点A, B的序号满足0 < |A - B| <= K,K<=8,问说一共有多少种方案。

    f[i][j][mask][k]表示考虑顶点0...i,使用j条边,前从i往前的K个顶点加上自己的的位状态是mask,并且考虑从i到i - k的连边方案的总方案数。

    则f[N - 1][M][0][K]就是答案。

    当顶点i处未连出边,则退化成i-1的情况。

    否则考虑从i到i-k的连边,

    如果不选择边,且i到i-k的连边继承自从i到i-(k-1)的连边,所以直接传递;

    如果选择边,则从边少1条的状态中传递。

    #include <iostream>
    using namespace std;

    const int MOD = 1000000007;

    typedef long long int64;

    int64 f[35][1 << 9][35][9];

    class DengklekBuildingRoads
    {
    public:
    int numWays(int N, int M, int K)
    {
    memset(f, 0, sizeof(f));
    for(int k = 0; k <= K; k++)
    f[0][0][0][k] = 1;
    //f[0][0][0][0] = 1;

    for(int i = 1; i < N; i++)
    {
    for(int j = 0; j <= M; j++)
    {
    // k = 0
    for(int mask = 0; mask < (1 << (K + 1)); mask++)
    {
    if(!(mask & 1)) f[i][mask][j][0] = f[i - 1][mask / 2][j][K];
    }
    // k > 0
    for(int k = 1; k <= K; k++)
    {
    for(int mask = 0; mask < (1 << (K + 1)); mask++)
    {
    f[i][mask][j][k] = f[i][mask][j][k - 1];
    if(k > i) continue;
    f[i][mask][j][k] += f[i][mask ^ 1 ^ (1 << k)][j - 1][k];
    f[i][mask][j][k] %= MOD;
    }
    }
    }
    }
    return f[N - 1][0][M][K];
    }
    };



  • 相关阅读:
    画板
    多线程
    Runtime
    今日头条UI搭建
    支付宝UI界面搭建
    控制器的创建
    UIWindow简单介绍
    UIApplication
    UIPickerView的使用
    代理、通知、KVO
  • 原文地址:https://www.cnblogs.com/litstrong/p/2363433.html
Copyright © 2011-2022 走看看