2016长乐夏令营 Day6
2016-07-15 19:58
309 查看
T1:
远古农场数小于等于10,意味着我们可以枚举远古农场的选择方案,这样原图中的所有点就被分为一定不能新建农场的点和可能可以新建农场的点。为了让新建的农场数量最大,农场显然是1*1最好,然后农场不能相邻,于是将可能可以建农场的点染成黑白两色(第一发代码在这里停止,直接贪心,居然过6个点。。强),就成了二分图,需要在里面找出一个最大独立子集,总点数-最大匹配就是了(Dicnic)又炸一波
T2:
f[a][b][c][d][i][j] 表示各种花色各选了a,b,c,d张,王的状态是i,j(0表示还没选),到当前目标的期望步数
转移见代码,特别注意的是王的转移就枚举后面的方案,贪心一下就好
转移的方式,就记忆化搜索吧
这大概是个DAG上的dp,反正。。。能找到的只有当前起点到当前终点的方案了
[b]T3:
想让距离和最小,显然点与点要按顺序连起来,然后,距离和最小时距离平方和最小,这东西是个二次函数,三分吧
远古农场数小于等于10,意味着我们可以枚举远古农场的选择方案,这样原图中的所有点就被分为一定不能新建农场的点和可能可以新建农场的点。为了让新建的农场数量最大,农场显然是1*1最好,然后农场不能相邻,于是将可能可以建农场的点染成黑白两色(第一发代码在这里停止,直接贪心,居然过6个点。。强),就成了二分图,需要在里面找出一个最大独立子集,总点数-最大匹配就是了(Dicnic)又炸一波
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<stack> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; const int maxn = 20; const int dx[4] = {0,1,0,-1}; const int dy[4] = {1,0,-1,0}; const int S = 0; const int T = 200; const int INF = ~0U>>1; struct Point{ int x,y; Point(int _x = 0,int _y = 0) {x = _x; y = _y;} }; struct E{ int from,to,cap,flow; E(int _from = 0,int _to = 0,int _cap = 0,int _flow = 0) {from = _from; to = _to; cap = _cap; flow = _flow;} }edgs[10000]; char p[maxn][maxn]; int t,n,m,ans,cnt,now,sum,tail,cur[210],que[210],vis[210], L[210],Num[maxn][maxn],q[maxn][maxn],Use[maxn],P[maxn][maxn]; bool arg[maxn][maxn],b[maxn]; vector <int> v[110]; queue <Point> Q; queue <int> Qu; int Draw(int i,int j) { q[i][j] = 1; Q.push(Point(i,j)); while (!Q.empty()) { Point k = Q.front(); Q.pop(); ++sum; for (int l = 0; l < 4; l++) { int xx = k.x + dx[l]; int yy = k.y + dy[l]; if (xx < 0 || xx == n || yy < 0 || yy == m) continue; if (P[xx][yy] == cnt || q[xx][yy] != -1) continue; q[xx][yy] = q[k.x][k.y] ^ 1; Q.push(Point(xx,yy)); } } } bool PreJudge() { for (int i = 0; i < 10; i++) for (int j = 0; j < 10; j++) if (Use[i] == cnt && Use[j] == cnt && arg[i][j]) return 0; return 1; } void Work() { for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) if ('0' <= p[i][j] && p[i][j] <= '9') { P[i][j] = cnt; if (Use[p[i][j] - '0'] == cnt) for (int l = 0; l < 4; l++) { int xx = i + dx[l]; int yy = j + dy[l]; if (xx < 0 || xx == n || yy < 0 || yy == m) continue; P[xx][yy] = cnt; } } } void Add(int from,int to,int w) { v[from].push_back(tail); edgs[tail++] = E(from,to,w,0); v[to].push_back(tail); edgs[tail++] = E(to,from,0,0); } bool BFS() { ++cnt; L[S] = 1; Qu.push(S); vis[S] = cnt; while (!Qu.empty()) { int k = Qu.front(); Qu.pop(); for (int i = 0; i < v[k].size(); i++) { E e = edgs[v[k][i]]; if (e.cap == e.flow) continue; if (vis[e.to] == cnt) continue; vis[e.to] = cnt; L[e.to] = L[k] + 1; Qu.push(e.to); } } return vis[T] == cnt; } int Dicnic(int x,int a) { if (x == T) return a; int flow = 0; for (int &i = cur[x]; i < v[x].size(); i++) { E &e = edgs[v[x][i]]; if (e.cap == e.flow) continue; if (L[x] + 1 != L[e.to]) continue; int F = Dicnic(e.to,min(a,e.cap - e.flow)); if (F > 0) { e.flow += F; edgs[v[x][i]^1].flow -= F; flow += F; a -= F; if (!a) return flow; } } return flow; } void Solve(int x) { int po = 0; ++cnt; now = sum = tail = 0; for (; x; x >>= 1) { if (x & 1) { if (!b[po]) return; Use[po] = cnt; ++now; } ++po; } bool flag = PreJudge(); if (!flag) return; Work(); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) q[i][j] = -1; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) if (P[i][j] != cnt && q[i][j] == -1) Draw(i,j); int Tail = 0; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) if (q[i][j] != -1) { if (q[i][j]) { Add(S,Num[i][j],1); for (int l = 0; l < 4; l++) { int xx = i + dx[l]; int yy = j + dy[l]; if (xx < 0 || xx == n || yy < 0 || yy == m) continue; if (!q[xx][yy]) Add(Num[i][j],Num[xx][yy],1); } } else Add(Num[i][j],T,1); que[++Tail] = Num[i][j]; } int flow = 0; while (BFS()) { for (int i = 1; i <= Tail; i++) cur[que[i]] = 0; cur[S] = cur[T] = 0; flow += Dicnic(S,INF); } for (int i = 1; i <= Tail; i++) v[que[i]].clear(); v[S].clear(); v[T].clear(); ans = max(ans,sum - flow + now); } void PRE() { scanf("%d%d",&n,&m); ans = 0; for (int i = 0; i < 10; i++) b[i] = 0; for (int i = 0; i < 10; i++) for (int j = 0; j < 10; j++) arg[i][j] = 0; for (int i = 0; i < n; i++) scanf("%s",p[i]); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) if ('0' <= p[i][j] && p[i][j] <= '9') { b[p[i][j] - '0'] = 1; for (int l = 0; l < 4; l++) { int xx = i + dx[l]; int yy = j + dy[l]; if (xx < 0 || xx == n || yy < 0 || yy == m) continue; if (p[xx][yy] != p[i][j] && p[xx][yy] != '.') arg[p[i][j]-'0'][p[xx][yy]-'0'] = 1; } } int SUM = 0; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) Num[i][j] = ++SUM; } int main() { #ifdef DMC freopen("DMC.txt","r",stdin); #else freopen("minecraft.in","r",stdin); freopen("minecraft.out","w",stdout); #endif cin >> t; for (int Case = 1; Case <= t; Case++) { PRE(); for (int i = 0; i < (1<<10); i++) Solve(i); printf("Case #%d: %d\n",Case,ans); } return 0; }
T2:
f[a][b][c][d][i][j] 表示各种花色各选了a,b,c,d张,王的状态是i,j(0表示还没选),到当前目标的期望步数
转移见代码,特别注意的是王的转移就枚举后面的方案,贪心一下就好
转移的方式,就记忆化搜索吧
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<stack> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; typedef double DB; DB f[16][16][16][16][5][5]; int T,cnt,A,B,C,D,vis[16][16][16][16][5][5]; DB DP(int a,int b,int c,int d,int i,int j) { if (vis[a][c][d][i][j] == cnt) return f[a][b][c][d][i][j] + 1.00; int a1 = a,b1 = b,c1 = c,d1 = d; if (i == 1) ++a1; if (j == 1) ++a1; if (i == 2) ++b1; if (j == 2) ++b1; if (i == 3) ++c1; if (j == 3) ++c1; if (i == 4) ++d1; if (j == 4) ++d1; if (a1 >= A && b1 >= B && c1 >= C && d1 >= D) return 1.00; f[a][b][c][d][i][j] = 0.00; vis[a][b][c][d][i][j] = cnt; int res = 54 - a - b - c - d; if (i) --res; if (j) --res; DB R = res; DB &F = f[a][b][c][d][i][j]; if (a < 13) F += (DB)(13-a)/R*DP(a+1,b,c,d,i,j); if (b < 13) F += (DB)(13-b)/R*DP(a,b+1,c,d,i,j); if (c < 13) F += (DB)(13-c)/R*DP(a,b,c+1,d,i,j); if (d < 13) F += (DB)(13-d)/R*DP(a,b,c,d+1,i,j); DB X = 1.00,Min = 1E16; if (!i) { for (int k = 1; k <= 4; k++) Min = min(Min,DP(a,b,c,d,k,j)); F += X/R*Min; Min = 1E16; } if (!j) { for (int k = 1; k <= 4; k++) Min = min(Min,DP(a,b,c,d,i,k)); F += X/R*Min; } return f[a][b][c][d][i][j] + 1.00; } int main() { #ifdef DMC freopen("DMC.txt","r",stdin); #else freopen("card.in","r",stdin); freopen("card.out","w",stdout); #endif DP(0,0,0,0,0,0); cin >> T; for (int Case = 1; Case <= T; Case++) { scanf("%d%d%d%d",&A,&B,&C,&D); int K = 0; DB ans = 0; if (A - 13 >= 0) K += A - 13; if (B - 13 >= 0) K += B - 13; if (C - 13 >= 0) K += C - 13; if (D - 13 >= 0) K += D - 13; if (K > 2) {printf("Case %d: -1\n",Case); continue;} ++cnt; DP(0,0,0,0,0,0); printf("Case %d: %.7f\n",Case,f[0][0][0][0][0][0]); } return 0; }
这大概是个DAG上的dp,反正。。。能找到的只有当前起点到当前终点的方案了
[b]T3:
想让距离和最小,显然点与点要按顺序连起来,然后,距离和最小时距离平方和最小,这东西是个二次函数,三分吧
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<stack> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; typedef double DB; const int maxn = 1E4 + 10; DB a[maxn*2]; int n; DB Work(DB now) { DB ret,po; ret = po = 0.00; for (int i = 1; i <= 2*n; i++) { po += 1.00; DB x = now + po - a[i]; //x -= a[i]; ret += sqrt(1.00 + x*x); } return ret; } int main() { #ifdef DMC freopen("DMC.txt","r",stdin); #else freopen("seg.in","r",stdin); freopen("seg.out","w",stdout); #endif cin >> n; for (int i = 1; i <= 2*n; i++) { int x; scanf("%d",&x); a[i] = x*1.00; } sort(a + 1,a + 2*n + 1); DB L,R; L = -1E9; R = 1E9; for (int i = 0; i < 100; i++) { DB T = (R-L)/3.00; DB mid1 = L + T; DB mid2 = L + T*2.00; DB ret1 = Work(mid1); DB ret2 = Work(mid2); if (ret1 > ret2) L = mid1; else R = mid2; } printf("%.13f",Work(L)); return 0; }
相关文章推荐
- 自我介绍-决心书
- 开发安全的web应用程序
- Java集合小结
- 【BZOJ-1336&1337】Alie最小圆覆盖 最小圆覆盖(随机增量法)
- IOS中json字符串原生数据请求&IOS跨平台AES128字符串加解密&AFNetworking框架的简单封装使用
- 软件构架、架构和框架的区别
- linux shell 自动输入y/yes
- js改变style样式和css样式
- OpenCV read video
- HDU 1162 Eddy's picture
- spring MVC框架下前台往java后台传送json数据
- 聪明的质监员(codevs 1138)
- 通过 Docker 化一个博客网站来开启我们的 Docker 之旅
- 归并排序
- SQLite简单理解常用方法与相关类
- dll's .h to dll's .lib
- oracle数据库操作
- jQuery 操作DOM总结,DOM Core操作,HTML-DOM操作和CSS-DOM操作
- 2016夏季练习——三分
- 火狐flash debug配置