Andrew Stankevich's Contest #2 Solution

这篇博客详细解析了Andrew Stankevich竞赛中的8道编程题目,涉及图论、动态规划、贪心策略等多个计算机科学领域。包括非吸收DFA问题、汉诺塔的扩展、超哈夫曼编码、小跳跃者问题、量化问题、道路优化、强盗问题以及Toral Tickets的染色方案。每道题目的解决方案都提供了相应的算法思想和标签。
摘要由CSDN通过智能技术生成

Andrew Stankevich's Contest #2

Solution

Problem A: NonAbsorbing DFA

Problem B: TheTowers of Hanoi Revisited

Problem C:Hyperhuffman

Problem D: LittleJumper

Problem E:Quantization Problem

Problem F: Roads

Problem G:Robbers

Problem H: ToralTickets

July 30th,2013 by chlxyd,xioumu

 

Problem A:Non Absorbing DFA

         给一个编译原理中的DFA图,图有一个起点,多个终点,图的边表示为一个F矩阵,f[i][j]表示i点用字母j可以连向f[i][j]点。还给了一个G,对于G[i][j] = 1表示,i点用字母j连出去的边时空边(也就是不会消耗字母j.

         求有多少不同的长度为N的字符串符合这个DFA图(可以重起点走到终点)

Solution

Tag:图论,DP

         若没有空边的话,直接用个简单的Dp就可以求出答案了,所以现在只要处理掉空边就行了。

         G(I,j)空边组成了一个环,那么到I节点的字母j永远不会走出环。所以若存在环,直接把环上的边都删了就行。

         G(i,j)没有组成环,那么直接把的G(I,j)指向这条路径上第一条非空边指向的点即可。

 

/*
 * Author:  chlxyd
 * Created Time:  2013/7/20 14:36:12
 * File Name: A.cpp
 */
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
using namespace std;
const double eps(1e-8);
typedef long long lint;
#define clr(x) memset( x , 0 , sizeof(x) )
#define sz(v) ((int)(v).size())
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repf(i, a, b) for (int i = (a); i <= (b); ++i)
#define repd(i, a, b) for (int i = (a); i >= (b); --i)
#define clrs( x , y ) memset( x , y , sizeof(x) )

const int maxn = 1000 + 10;
int vs[maxn], vt[maxn], v[maxn];
int n, m, len, S, tn;
char word[maxn];
vector<int> e[maxn], wo[maxn], g[maxn];

void add(vector<int> *e, vector<int> *wo, int x, int y, int w) { 
    e[x].push_back(y);
    wo[x].push_back(w);
}

void add2(int x, int y) {
    g[x].push_back(y);
}

void init() {
    scanf("%s", word); 
    m = strlen(word);
    scanf("%d", &n);
    scanf("%d%d", &S, &tn);
    clr(vs);
    clr(vt);
    S--;
    vs[S] = 1;
    rep (i, tn) {
        int x;
        scanf("%d", &x);
        x--;
        vt[x] = 1;
    }
    rep (i, n) {
        e[i].clear();
        g[i].clear();
        wo[i].clear();
    }
    //printf("%d %d\n", n, m);
    rep (i, n)
        rep (j, m) { 
            int x;
            scanf("%d", &x);
            x--;
            add(e, wo, i, x, j);
        }
    rep (i, n) 
        rep (j, m) {
            int x;
            scanf("%d", &x);
            add2(i, x); 
        }
    scanf("%d", &len);
    //printf("%d\n", len);
}

int dfs(int x, int w) {
    if (v[x]) return -1;
    v[x] = 1;
    rep (i, sz(e[x])) {
        if (w == wo[x][i]) {
            int j = e[x][i];
            if (g[x][i]){
                int h = dfs(j, w);
                if (h == -1) 
                    return -1;
                e[x][i] = h;
                g[x][i] = 0; 
                return h;
            }
            else if (!g[x][i]) {
                return j; 
            }
        }
    }
    return -1;
}

void getG2() {
    rep (i, n) {
       rep (k, sz(e[i])) {
            if (g[i][k]) {
                memset(v, 0, sizeof(v));
                dfs(i, wo[i][k]);
            }
       } 
    } 
}

void add(vector<int> &a, vector<int> b) {
    int an = sz(a), bn = sz(b);
    rep (i, min(an, bn)) {
        a[i] += b[i];
    } 
    repf (i, an, bn - 1) {
        a.push_back(b[i]);
    }
    rep (i, max(an, bn)) {
        if (a[i] >= 10) {
            if (i + 1 >= sz(a))
                a.push_back(0);
            a[i + 1] += a[i] / 10;
            a[i] %= 10;
        }
    }
}

void myset(vector<int> &a, int w) {
    a.clear();
    a.push_back(w);
}

void myput(vector<int> &a) {
    repd (i, sz(a) - 1, 0) {
        printf("%d", a[i]);
    }
    puts("");
}

vector<int> f[70][maxn];
//int f[70][maxn];

void ga
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值