Solution

注意取模!!!

Code

#include<bits/stdc++.h>
#define mod 1000000007
#define LL long long
using namespace std; int n, a, b; LL mpow(LL a, LL b) {
LL ans = ;
for(; b; b >>= , a = a * a % mod)
if(b & ) ans = ans * a % mod;
return ans;
} LL fac[], inv[], l[], t[];
void init() {
fac[] = ;
inv[] = ;
for(int i = ; i <= ; i ++) {
fac[i] = fac[i - ] * i % mod;
inv[i] = mpow(fac[i], mod - );
}
} LL C(int p, int q) {
return fac[p] * inv[q] % mod * inv[p - q] % mod;
} int main() {
freopen("matrix.in", "r", stdin);
freopen("matrix.out", "w", stdout);
scanf("%d%d%d", &n, &b, &a);
for(int i = ; i <= n; i ++) scanf("%lld", &l[i]);
for(int i = ; i <= n; i ++) scanf("%lld", &t[i]);
LL ans = ;
init();
for(int i = ; i <= n; i ++) {
ans = (ans + b * l[i] % mod * C(n - + n - i, n - ) % mod * mpow(a, n - i) % mod * mpow(b, n - ) % mod) % mod;
ans = (ans + a * t[i] % mod * C(n - + n - i, n - ) % mod * mpow(b, n - i) % mod * mpow(a, n - ) % mod) % mod;
}
printf("%lld", ans);
return ;
}

Solution

二分+DP,二分需要多少组p+q,记忆化搜索判断是否可以达到条件。

定义$dp[dep][j][k]$表示当前取到第$dep$个数,还需要j个p,k个q来使满足条件。(p>q)

每次先尽量放p,剩下中再尽量放q,放q时就有限制,不能取超过$mid-i$,i表示当前取的p的数量。

Code

#include<bits/stdc++.h>
using namespace std; int n, a[], p, q;
int sum[], vis[][][], tim, all;
bool dfs(int dep, int nump, int numq) {
if(nump == && numq == ) return ;
if(dep == n + || sum[dep] < nump * p + numq * q) return ;
if(vis[dep][nump][numq] == tim) return ;
for(int i = ; i <= min(nump, a[dep] / p); i ++)
if(dfs(dep + , nump - i, max(numq - min((a[dep] - p * i) / q, all - i), ))) return ;
vis[dep][nump][numq] = tim;
return ;
} bool check(int mid) {
tim ++;
all = mid;
return dfs(, mid, mid);
} int erfen() {
int l = , r = sum[] / (p + q), ans;
while(l <= r) {
int mid = (l + r) >> ;
if(check(mid)) ans = mid, l = mid + ;
else r = mid - ;
}
return ans;
} int main() {
freopen("pq.in", "r", stdin);
freopen("pq.out", "w", stdout);
scanf("%d", &n);
for(int i = ; i <= n; i ++) scanf("%d", &a[i]);
for(int i = n; i >= ; i --) sum[i] = sum[i + ] + a[i];
scanf("%d%d", &p, &q);
if(p < q) swap(p, q);
int ans = erfen();
printf("%d", ans * (p + q));
return ;
}

Solution

考试最后半小时开始写QAQ结果发现是做过的题啊??

可是最后Spfa写错了!!!我爆哭!!!!

将与1相连的所有点取出来,二进制分类,分成起点和终点,跑多起点多终点的Spfa,处理出两两起点终点间最短路,更新答案即可QAQ

Spfa要判更新的点不能是1!!

Code

#include<bits/stdc++.h>
using namespace std; int n, m; struct Node {
int v, nex, w;
} Edge[]; int h[], stot = ;
void add(int u, int v, int w) {
Edge[++stot] = (Node) {v, h[u], w};
h[u] = stot;
} int dis[];
int vis[], nums, numt, w[], t[], S[], T[];
void Spfa1() {
queue < int > q;
memset(vis, , sizeof(vis));
memset(dis, 0x3f3f3f3f, sizeof(dis));
for(int i = ; i <= nums; i ++) q.push(S[i]), vis[S[i]] = , dis[S[i]] = min(dis[S[i]], w[S[i]]);
while(!q.empty()) {
int u = q.front(); q.pop(); vis[u] = ;
for(int i = h[u]; i; i = Edge[i].nex) {
int v = Edge[i].v;
if(dis[v] > dis[u] + Edge[i].w && v != ) {
dis[v] = dis[u] + Edge[i].w;
if(!vis[v]) {
vis[v] = ; q.push(v);
}
}
}
}
} void Spfa2() {
queue < int > q;
memset(vis, , sizeof(vis));
memset(dis, 0x3f3f3f3f, sizeof(dis));
for(int i = ; i <= numt; i ++) q.push(T[i]), vis[T[i]] = , dis[T[i]] = min(dis[T[i]], w[T[i]]);
while(!q.empty()) {
int u = q.front(); q.pop(); vis[u] = ;
for(int i = h[u]; i; i = Edge[i].nex) {
int v = Edge[i].v;
if(dis[v] > dis[u] + Edge[i].w && v != ) {
dis[v] = dis[u] + Edge[i].w;
if(!vis[v]) {
vis[v] = ; q.push(v);
}
}
}
}
} int tov[], tot;
int main() {
freopen("graph.in", "r", stdin);
freopen("graph.out", "w", stdout);
scanf("%d%d", &n, &m);
for(int i = ; i <= m; i ++) {
int u, v, a, b;
scanf("%d%d%d%d", &u, &v, &a, &b);
add(u, v, a); add(v, u, b);
}
int ans = 0x3f3f3f3f;
memset(w, 0x3f3f3f3f, sizeof(w));
memset(t, 0x3f3f3f3f, sizeof(t));
for(int i = h[]; i; i = Edge[i].nex)
tov[++tot] = Edge[i].v, w[Edge[i].v] = min(w[Edge[i].v], Edge[i].w), t[Edge[i].v] = min(t[Edge[i].v], Edge[i ^ ].w);
sort(tov + , tov + + tot);
int M = tov[tot], tt = ;
while(M) {
int tmp = (M & );
nums = , numt = ;
for(int i = ; i <= tot; i ++)
if(((tov[i] >> tt) & ) == tmp) S[++nums] = tov[i];
else T[++numt] = tov[i];
Spfa1();
for(int j = ; j <= numt; j ++) {
ans = min(ans, t[T[j]] + dis[T[j]]);
}
Spfa2();
for(int j = ; j <= nums; j ++) {
ans = min(ans, t[S[j]] + dis[S[j]]);
}
M >>= , tt ++;
}
printf("%d", ans);
return ;
}

【10.31校内测试】【组合数学】【记忆化搜索/DP】【多起点多终点二进制拆位Spfa】的更多相关文章

  1. 记忆化搜索(DP+DFS) URAL 1183 Brackets Sequence

    题目传送门 /* 记忆化搜索(DP+DFS):dp[i][j] 表示第i到第j个字符,最少要加多少个括号 dp[x][x] = 1 一定要加一个括号:dp[x][y] = 0, x > y; 当 ...

  2. 记忆化搜索 dp学习~2

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1331 Function Run Fun Time Limit: 2000/1000 MS (Java/ ...

  3. BZOJ1048:[HAOI2007]分割矩阵(记忆化搜索DP)

    Description 将一个a*b的数字矩阵进行如下分割:将原矩阵沿某一条直线分割成两个矩阵,再将生成的两个矩阵继续如此分割(当然也可以只分割其中的一个), 这样分割了(n-1)次后,原矩阵被分割成 ...

  4. hdu 4960 记忆化搜索 DP

    Another OCD Patient Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Ot ...

  5. HNU OJ10086 挤挤更健康 记忆化搜索DP

    挤挤更健康 Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit users: 339, A ...

  6. HDU 1078 FatMouse and Cheese 记忆化搜索DP

    直接爆搜肯定超时,除非你加了某种凡人不能想出来的剪枝...555 因为老鼠的路径上的点满足是递增的,所以满足一定的拓补关系,可以利用动态规划求解 但是复杂的拓补关系无法简单的用循环实现,所以直接采取记 ...

  7. hdu1331&&hdu1579记忆化搜索(DP+DFS)

    这两题是一模一样的``` 题意:给了一系列递推关系,但是由于这些递推很复杂,所以递推起来要花费很长的时间,所以我要编程序在有限的时间内输出答案. w(a, b, c): 如果a,b,c中有一个值小于等 ...

  8. HDU - 6415 多校9 Rikka with Nash Equilibrium(纳什均衡+记忆化搜索/dp)

    Rikka with Nash Equilibrium Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K ...

  9. [P2921][USACO08DEC]在农场万圣节Trick or Treat on the Farm (记忆化搜索/DP?,Tarjan?)

    第一看还以为是水题 随便打了一个bfs只有40分…… 然后开始颓废 #include<bits/stdc++.h> #define N 100005 using namespace std ...

随机推荐

  1. bzoj千题计划267:bzoj3129: [Sdoi2013]方程

    http://www.lydsy.com/JudgeOnline/problem.php?id=3129 如果没有Ai的限制,就是隔板法,C(m-1,n-1) >=Ai 的限制:m减去Ai &l ...

  2. python 基础知识 列表的 增删改查 以及迭代取值

    """ python 列表 通用方法 元组.数组.字典 取值方法 [] 列表中可以存储不同类型的数据 函数 封装了独立的功能可以直接调用 函数名(参数) 方法 和函数类似 ...

  3. js 正则学习小记之匹配字符串字面量优化篇

    昨天在<js 正则学习小记之匹配字符串字面量>谈到 个字符,除了第一个 个,只有 个转义( 个字符),所以 次,只有 次成功.这 次匹配失败,需要回溯后用 [^"] 才能匹配成功 ...

  4. Django Book 学习笔记(上)

    拜读了网上的Django Book,现在来总结一下吧...... 一.Django的配置 非常的蛋疼,由于Django的块组之间耦合度低,这既是它的优点,也是它的缺点.我在Ubuntu所配置的Djan ...

  5. ListUtil(差集、交集、并集)

    package cn.fraudmetrix.octopus.horai.biz.utils; import java.util.ArrayList; import java.util.Arrays; ...

  6. parallelogram

    The parallelogram law in inner product spaces Vectors involved in the parallelogram law. In a normed ...

  7. python之celery使用详解(二)

    前言 前面我们了解了celery的基本使用后,现在对其常用的对象和方法进行分析. Celery对象 核心的对象就是Celery了,初始化方法: class Celery(object): def __ ...

  8. 设置adb server的端口号

    在操作系统的系统环境里面,加一个环境变量: ANDROID_ADB_SERVER_PORT,值为9999,看自己喜欢.

  9. vue 兼容IE报错解决方案

    IE 页面空白 报错信息 此时页面一片空白 报错原因 Babel 默认只转换新的 JavaScript 语法(如箭头函数),而不转换新的 API ,比如 Iterator.Generator.Set. ...

  10. 输出联系变化的数字seq

    主要作用:输出联系变化的数字格式:Seq 分割符号 开始 间隔 结束开始默认是1,间隔默认是1,分隔符默认回车一位是结束,两位首末,三位首间隔末,没有四位,开始可以是负数主要参数:-f 指定格式打印- ...