2012 Multi-University Training Contest 3[hdu4320~4330]

 hdu4222 candy

 http://acm.hdu.edu.cn/showproblem.php?pid=4322

费用流 看题解构图过的, 同时利用了边的费用和流量 题解这里,

【题目大意】

有N颗糖果和M个小孩,老师现在要把这N颗糖分给这M个小孩。每个小孩i对每颗糖j都有一个偏爱度Aij,如果他喜欢这颗糖,Aij = k,否则Aij = 1。小孩i觉得高兴当且仅当ΣCij×Aij >= Bi,j=1,2,…,N,若他分得了糖j,Cij = 1,否则Cij = 0。问能否合理分配这N颗糖,使得每个小孩都觉得高兴。

【建模方法】

(最大费用最大流)

         本题有一个突破点就是:他喜欢这颗糖,Aij = k,否则Aij = 1,关键在于如果他不喜欢这个糖分给他一样可以获得1点的欢乐值。也就是说如果之前分配了的糖给了小孩一定的欢乐值,不够bi,可以直接用随意的糖去填满。

首先我们要求欢喜值>=bi,是否可以认为当我获得欢喜值为bi后,多余欢喜值对这个结果的满足是没有贡献的。也就是说,你可以用一个容量来控制分配糖对小孩欢喜值的控制,让获得欢喜值最多为bi。如果不够,最后用一些1的糖来填满。

而这个容量就是bi/c,获取贡献为k,bi%c(>1)的也是可以用一个能让这个小孩欢喜的糖来贡献,但是其费用只为bi%c。

对于小孩来说,最大费用最大流后,糖分配的贡献值为最大费用,剩余糖就是(n-最大流),然后用这些糖去填不满的,只要满足总和大于Σbj。就可以分配了。

具体建模方案1:

(s,i,1,0);

(i,j,1,0);

(j,t,bj/k,k);

If(bj%k>1)

(j,t,1,bj%k)

Ans = 费用 + N – 最大流 >= Σbj  则满足要求

 

 

 hdu4223 BKTree 编辑距离

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <map>
#include <vector>
#include <string>
#include <algorithm>

const double pi=cos(-1.);
const double eps=10e-6;
const double eps1=10e-10;
const int inf=0x7fffffff;
const long long infl=1ll<<62;

///******macro defination******///
#define cas(a) int a; scanf("%d", &a); while (a--)
#define cas1(x, a) int a; scanf("%d", &a); for (int x=1; x<=a; ++x)
#define int(a) int a; scanf("%d", &a)
#define char(a) char a; scanf("%c", &a)
#define strr(a, x) char a[x]; scanf("%s", &a)
#define clean0(a) memset (a, 0, sizeof(a));
#define clean(a, x) memset (a, x, sizeof(a));
#define copy(a, b) memcpy(a, b, sizeof(a));
#define up(x,a) for(int x=0; x<a; ++x)
#define down(x,a) for(int x=a-1; x>=0; --x)
#define up1(x,a) for (int x=1; x<=a; ++x)

#define debug(a) printf("here is %d!!!\n", a);
///*** mathmatics ***///
#define sqr(x) (x)*(x)
#define abs(x) (x)>0?(x):(-(x))
#define zero(x) (x)<eps && (x)>eps
///******   by Geners   ******///
typedef long long ll;
typedef unsigned int UI;

using namespace std;

const int maxn=1555;
struct BKTree{
    char str[15];
    int son[25];
}node[maxn];
int idx;
int Levenshtein(char*, char*);

void initBK(int r, char* v)
{
    copy(node[r].str, v);
    clean(node[r].son, -1);
}

void insert(int r, char* str)
{
    int dist=Levenshtein(node[r].str, str);
    if(dist)
    {
        if(node[r].son[dist]==-1)
        {
            initBK(idx, str);
            node[r].son[dist]=idx++;
        }
        else insert(node[r].son[dist], str);
    }
}

int find(int r, char *str, int d)
{
    if(r==-1)return 0;
    int dist=Levenshtein(node[r].str, str);
    //printf("%d r=%d %s %s\n", dist, r, str, node[r].str);
    int ret=(dist<=d);
    for (int i=max(1, dist-d); i<=dist+d; ++i)
    {
        ret+=find(node[r].son[i], str, d);
    }
    return ret;
}

int Levenshtein(char *s1, char *s2)
{
    int dp[20][20];
    int l1=strlen(s1), l2=strlen(s2);
    for (int i=0; i<=l1; ++i)dp[i][0]=i;
    for (int i=0; i<=l2; ++i)dp[0][i]=i;
    for (int j=0; s1[j]; ++j)
    {
        for (int k=0; s2[k]; ++k)
        {
            dp[j+1][k+1]=min(dp[j][k+1]+1,dp[j+1][k]+1);
            dp[j+1][k+1]=min(dp[j+1][k+1], dp[j][k]+(s1[j]!=s2[k]));
        }
    }
    //printf("%d =d(%s %s)\n", dp[l1][l2], s1, s2);
    return dp[l1][l2];
}




int main()
{
    //freopen("1004.in", "r", stdin);
    //freopen("1004a.out", "w", stdout);
    int cas; scanf("%d", &cas);
    for (int I=1; I<=cas; ++I)
    {
        int n, m; scanf("%d%d", &n, &m);
        char str[20];
        idx=0;
        scanf("%s", str); initBK(idx++, str);
        for (int i=1; i<n; ++i)
        {
            scanf("%s", str); insert(0, str);
        }
        printf("Case #%d:\n", I);
        up(p, m)
        {
            char ss[20]; int a; scanf("%s%d", ss, &a);
            printf("%d\n", find(0, ss, a));
        }
    }
    return 0;
}
/*
2
5 2
656
67
9313
1178
38
87 1
9509 1

5 2
656
67
9313
1178
38
87 1
9319 1

*/



 

hdu 4328 cut the cake

http://acm.hdu.edu.cn/showproblem.php?pid=4328

O(n^2)求最大01矩阵周长

原型题求面积 hdu1505 没看懂题解的方法, 只知道这个方法是O(N^2)的 ,而且能ac.囧

int rectangle(int m)
{
    int res=0;
    for (int i=0; i<maxn; ++i)l[i]=r[i]=i;
    for (int i=0; i<m; ++i)
        while (l[i]-1>=0 && h[l[i]-1]>=h[i])l[i]=l[l[i]-1];
    for (int i=m-1; i>=0; --i)
        while (r[i]+1<m && h[r[i]+1]>=h[i])r[i]=r[r[i]+1];

    for (int i=0; i<m; ++i)
        if(h[i])res=max(res, h[i]+r[i]-l[i]+1);
        //,printf("%d %d %d \n", h[i], l[i], r[i]);
    return res<<1;
}

int square(int n, int m)
{
    for (int i=0; i<m; ++i)dp[0][i]=1;
    for (int i=0; i<n; ++i)dp[i][0]=1;

    for (int i=1; i<n; ++i)
    {
        for (int j=1; j<m; ++j)
        {
            if(imap[i][j]!=imap[i-1][j] && imap[i][j]!=imap[i][j-1])
            {
                int limit=min(dp[i][j-1], dp[i-1][j]);
                dp[i][j]=limit+(imap[i-limit][j-limit]==imap[i][j]);
            }
            else dp[i][j]=1;
        }
    }
    int res=0;
    for (int i=0; i<n; ++i) for (int j=0; j<m; ++j) res=max(res, dp[i][j]);
    return res<<2;
}

int main ()
{
//    freopen("1009.in", "r", stdin);
//    freopen("1009a.out", "w", stdout);
    int cas; scanf("%d", &cas);
    for (int I=1; I<=cas; ++I)
    {
        int n, m; scanf("%d%d", &n, &m);
        char str[maxn];
        for (int i=0; i<n; ++i)
        {
            scanf("%s", str);
            for (int j=0; j<m; ++j)
            {
                imap[i][j]=(str[j]=='B');
            }
        }
        int tmp=square(n, m);
        //printf("%d\n", tmp);
        clean(h, 0);
        for (int i=0; i<n; ++i)
        {
            for (int j=0; j<m; ++j)
            {
                if(imap[i][j])h[j]++;
                else h[j]=0;
            }
            tmp=max(rectangle(m), tmp);
            //printf("Case #%d: %d in %d\n", I, rectangle(m), i);
        }
        clean(h, 0);
        for (int i=0; i<n; ++i)
        {
            for (int j=0; j<m; ++j)
            {
                if(imap[i][j])h[j]=0;
                else h[j]++;
            }
            tmp=max(rectangle(m), tmp);
        }
        printf("Case #%d: %d\n", I, tmp);
    }
    return 0;
}


 

 

你可能感兴趣的:(c,struct,insert,UP,Training)