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. 卸载并安装指定版本Angular CLI

    1.卸载之前的版本 npm uninstall -g @angular/cli 2.清除缓存,确保卸载干净 npm cache clean 3.检查是否卸载干净 输入命令 ng -v 若显示comma ...

  2. java注解 @SuppressWarnings注解用法

    @SuppressWarnings注解用法 @SuppressWarnings注解主要用在取消一些编译器产生的警告对代码工具左侧行列提示,但这种警告可以通过注释类型声明来取消 @SuppressWar ...

  3. 获取SQL Server数据库中的表和字段描述

    获取所有dbo表的扩展属性: SELECT * FROM fn_listextendedproperty (NULL, 'schema', 'dbo', 'table', default, NULL, ...

  4. 20155215 2016-2017-2 《Java程序设计》第7周学习总结

    20155215 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 第十二章 lambda语法:Lambda去重复,回忆DRY原则,Lambda表达式可读性更好 ...

  5. 第5月第16天 php crud CodeIgniter CI_DB_active_record

    1.C.R.U.D. Generator for CodeIgniter https://github.com/antonioyee/crud-generator/tree/9e5e48e773a52 ...

  6. 正则匹配URL地址

    import re u = "http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]) ...

  7. 关于markdown文件插入图片遇到的小问题和解决办法

    今天用md文件时候发现需要插入图片,以前没做过,所以写下来分享下. 1.先在自己的github上建一个仓库,里面新建个img文件夹存放图片,怎么建仓库可以上网找资料,这里就不详细说明了.建好的仓库如下 ...

  8. hibernate介绍及环境搭建

    1.前言 hibernate与mybatis的位置一样,都是属于DAO层的框架,代替我们原来的JDBC操作数据库,属于ORM(object relationg mapping. 对象关系映射)框架.O ...

  9. 【ARTS】01_08_左耳听风-20181231~20190106

    ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...

  10. 通过anaconda进行python多版本控制

    ---恢复内容开始--- linux与windows通用. 1. 假设电脑上已经转好anaconda3. (anaconda 默认装好了python3.jupyter.spyter) 2. 现在需求是 ...