A

  简单的差分约束模型 , 因为d是定值 , 所以也可以按最短路理解 , trick是不能把圈算进去.

  

 #define maxn 55
class Egalitarianism {
public:
int maxDifference(vector <string>, int);
};
int e[maxn][maxn],n,f[maxn][maxn];
int Egalitarianism::maxDifference(vector <string> isFriend, int d) {
n = isFriend.size();
memset(e,-,sizeof(e));
for (int i= ; i<n ; i++ ) {
for (int j= ; j<n ; j++ ) if (isFriend[i][j]=='Y') {
e[i][j] = d;
}
}
int ans = -;
for (int k= ; k<n ; k++ ) {
for (int i= ; i<n ; i++ ) {
for (int j= ; j<n ; j++ ) if (e[i][k] != - && e[k][j] != -) {
if (e[i][j]==- || e[i][j]>e[i][k] + e[k][j])
e[i][j] = e[i][k]+e[k][j];
}
}
}
for (int i= ; i<n ; i++ ) for (int j= ; j<n ; j++ ) if (i!=j){
if (e[i][j] == -) return -;
ans = max(ans,e[i][j]);
}
return ans;
}

B

  计数模型很好想 , 但是有很多细节要想清楚 , 一开始想简单了......

  离散化之后 , dp[i][j][k] 表示满足要求的方案数:

  (1) 挖了前i种东西;

  (2) 所以挖出来的东西最大深度为j;

  (3) 挖出来了k个;

  (4) 每个都是在found里出现的;

  然后 ans = sigma ( dp[51][j][k] * factor[j][k] ) (1<=j<INF , found.size()<=j<=K);

  比较麻烦的地方在对于给定的状态 , 计算对应factor:

  (1)  还要挖 K-k个 , 并且他们的深度大于j , 即不能被发现;

  (2)  要把所有的building考虑进去,而不仅仅是不在found里面的;

  (3)  必须保证接下来挖的中,深度最小的building未在found里出现 , 否则会重复计数;

  

 using namespace std;
#define maxn 60
#define maxd 100010
#include <cstring>
const int INF = maxd-;
typedef long long llong; class Excavations {
public:
long long count(vector <int>, vector <int>, vector <int>, int);
}; bool in[maxn];
llong c[maxn][maxn] , b[maxn][maxn][maxn] ;//, s[maxn][maxn][maxn] , s2[maxn][maxn][maxn];
int cnt[maxn],n,m,D;
map<int,int> hk , hd;
vector<int> bufk , bufd , t[maxn]; struct node{
int k,d;
};node build[maxn]; bool cmp (node a , node b) {
if (a.k == b.k) return a.d<b.d;
return a.k<b.k;
}
void pretreat(vector<int> kind,vector<int> depth,vector<int> found) {
n = kind.size();
m = found.size();
bufd.push_back();
bufd.push_back(INF);
bufk.push_back();
for (int i= ; i<n ; i++ ) bufk.push_back(kind[i]) , bufd.push_back(depth[i]);
sort(bufd.begin(),bufd.end());
sort(bufk.begin(),bufk.end());
bufd.erase( unique(bufd.begin(),bufd.end()) , bufd.end() ) ;
bufk.erase( unique(bufk.begin(),bufk.end()) , bufk.end() ) ;
for (int i= ; i<(int)bufk.size() ; i++ ) hk[bufk[i]] = i;
for (int i= ; i<(int)bufd.size() ; i++ ) hd[bufd[i]] = i;
for (int i= ; i<n ; i++ ) build[i] = (node){hk[kind[i]] , hd[depth[i]]};
sort(build,build+n,cmp);
for (int i= ; i<m ; i++ ) in[hk[found[i]]] = ;
for (int i= ; i<= ; i++ ) {
c[i][] = ;
for (int j= ; j<=i ; j++ ) c[i][j] = c[i-][j-] + c[i-][j];
}
D = hd[maxd-];
for (int i= ; i<=D ; i++ ) {
for (int j= ; j<n ; j++ ) if (build[j].d>=i)
cnt[i] ++;
}
for (int i= ; i<n ; i++ ) t[build[i].k].push_back(build[i].d);
for (int i= ; i<= ; i++ ) sort(t[i].begin() , t[i].end());
} long long Excavations::count(vector <int> kind, vector <int> depth, vector <int> found, int K) {
pretreat(kind,depth,found); b[][][] = ;
for (int i= ; i< ; i++ )
for (int j= ; j<D ; j++ )
for (int k= ; k<=K ; k++ ) if (b[i][j][k]) { //printf("b[%d][%d][%d]=%lld\n",i,j,k,b[i][j][k]); int debug = ;
if (j==) debug = ; if (in[i+]) {// printf("t[%d].size()=%d\n",i+1,(int)t[i+1].size()); for (int x=0 ; x<(int)t[i+1].size() ; x++ ) printf("%d ",t[i+1][x]); printf("\n");
for (int x= ; x<(int)t[i+].size() ; x++ )
for (int y= ; y<=x ; y++ ) {
if (y++k>K) break;
int dep = max(j, t[i+][x]);
b[i+][dep][y++k] += b[i][j][k] * c[x][y];
if (debug) {
// printf("b[%d][%d][%d] add %lld * c[%d][%d](%lld) = %lld\n",i+1,dep,y+1+k,b[i][j][k],x,y,c[x][y],b[i][j][k]*c[x][y]);
}
}
} else {
b[i+][j][k] += b[i][j][k];
// if (debug) printf("b[%d][%d][%d] add %lld\n",i+1,j,k,b[i][j][k]);
}
}
llong ans = ; vector<int> illegal;
int f[maxn];
memset(f,,sizeof(f));
for (int i= ; i<n ; i++ ) if (!in[build[i].k]) {
illegal.push_back(build[i].d);
f[build[i].d] ++ ;
}
sort(illegal.begin(),illegal.end());
illegal.erase( unique(illegal.begin(),illegal.end()) , illegal.end() ); for (int i= ; i<D ; i++ )
for (int j=m ; j<=K ; j++ ) if (b[][i][j]) {
if (j==K) {
ans += b[][i][j];
printf("add: b[%d][%d]=%lld\n",i,j,b[][i][j]);
}
else {
llong fct = ;
for (int x= ; x<(int)illegal.size() ; x++ ) if (illegal[x]>i) {
int d = illegal[x];
int need = K-j;
for (int y= ; y<=need && y<=f[d] ; y++ ) {
fct += c[f[d]][y] * c[cnt[d]-f[d]][need-y];
printf("fct add: c[%d][%d] * c[%d][%d] = %lld\n",f[d],y,cnt[d]-f[d],need-y,c[f[d]][y]*c[cnt[d]-f[d]][need-y]);
}
}
ans += b[][i][j] * fct;
}
}
return ans;
}

C

  裸的斯坦纳树。。。字符串处理可以这样写:

 string s = "";
for (int i= ; i<(int)courseInfo.size() ; i++ ) s += courseInfo[i];
stringstream ss(s);
string t;
while (ss>>t) {
sscanf(t.c_str(),"%c%d->%c%d:%d",&a,&da,&b,&db,&cst);
int pa , pb;
pa = encode((int)(a-'A'),da);
pb = encode((int)(b-'A'),db);
addedge(pb,pa,cst);
}

  斯坦纳树有2部分更新:

  (1) 对确定的根v , 用mask的子集更新: dp[v][mask] = min ( dp[v][submask] + dp[v][mask - submask])

  本质上是寻找树最优的组合结构,不会有松弛.

  (2) 对确定的根v , 用点u松弛: dp[v][mask] = min ( dp[v][mask] , dp[u][mask] + 最短路(u,v) )

  

SRM 584 DIV1的更多相关文章

  1. Topcoder SRM 584 DIV1 600

    思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...

  2. Topcoder SRM 643 Div1 250<peter_pan>

    Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...

  3. Topcoder Srm 726 Div1 Hard

    Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...

  4. 图论 SRM 674 Div1 VampireTree 250

    Problem Statement      You are a genealogist specializing in family trees of vampires. Vampire famil ...

  5. TC SRM 584 DIV 2

    第一次在DIV2 AK了. 250水题. 500,FLoyd搞出所有边的最短路,然后找最短路,中最长的,如果有不连通的边返回-1 1000,组合DP,各种慌乱,在最后1分钟时,交上了,感觉很棒,最后还 ...

  6. SRM 584 第一次玩TopCoder。。。只水题一道。。。

    第一次topcoder,以前老感觉没有资格去做tc,cf什么的,现在已经慢慢接触了. 感觉还可以,还是有让我们这些蒻菜安慰的水题. tc的确很好玩,用客户端比赛,还有各种规则,而且还是只编写一个类提交 ...

  7. SRM 583 DIV1

    A 裸最短路. class TravelOnMars { public: int minTimes(vector <int>, int, int); }; vector<int> ...

  8. SRM 590 DIV1

    转载请注明出处,谢谢viewmode=contents">http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlov ...

  9. Topcoder SRM 602 div1题解

    打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...

随机推荐

  1. Python | 基础系列 · Python为什么没有switch/case语句?

    与我之前使用的所有语言都不同,Python没有switch/case语句.为了达到这种分支语句的效果,一般方法是使用字典映射: def numbers_to_strings(argument): sw ...

  2. redis 中文手册

    https://redis.readthedocs.org/en/latest/ http://www.cnblogs.com/ikodota/archive/2012/03/05/php_redis ...

  3. ansible小结

    一.Ansible的安装 1.yum源安装 以centos为例,默认在源里没有ansible,不过在fedora epel源里有ansible,配置完epel 源后,可以直接通过yum 进行安装.这里 ...

  4. KMP学习笔记

    功能 字符串T,长度为n. 模板串P,长度为m.在字符串T中找到匹配点i,使得从i开始T[i]=P[0], T[i+1]=P[1], . . . , T[i+m-1]=P[m-1] KMP算法先用O( ...

  5. servlet中访问mysql无法包含中文的解决

    最近写servlet应用发现,如果我的sql语句中包含英文,访问数据库就失败,而我数据库的编码是utf8 -- UTF-8 Unicode,而我servlet的字符也已经转为UTF-8 ,还是不行. ...

  6. C#解leetcode 106. Construct Binary Tree from Inorder and Postorder Traversal

    Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  7. 转载:C#实现接口回调

    通常情况下,我们创建一个对象,并马上直接去使用它的方法.然而,在有些情况下,希望能在某个场景出现后或条件满足时才调用此对象的方法.回调就可以解决这个“延迟调用对象方法”的问题.这个被调用方法的对象称为 ...

  8. dedecms调用所有顶级栏目最新文章的实现方法

    做dedecms的模板,我们会遇到各种各样的调用问题,dedecms列表页调用所有顶级栏目文章列表的方法如下所述: 在文章页面经常使用的是 {dede:arclist orderby='pubdate ...

  9. CI 模型的使用M与C之间的调用

    CI是PHP一个比较轻,并且好用的一个框架 分层也是分的比较清晰的一个 这里先展示MODEL 放在application/models 目录下面user_model.php <?php clas ...

  10. Mac OS X 10.9 Mavericks 修改root密码

    Mac10.9忘记密码后有两种方式可以进去:  代码如下 复制代码 1.sudo passwd 重新输入密码即可,此方法修改了root的密码  代码如下 复制代码 2.sudo bash 输入当前用户 ...