#2016 10 28 考试
####时间 7:50 AM to 11:15 AM


下载链接:

试题

考试包


这次考试对自己的表现非常不满意!!

T1看出来是dp题目,但是在考试过程中并没有推出转移方程,考虑了打表,但是发现暴力程序的速度不够,直接交了暴力,没想到暴力程序爆0,考试后仔细查找发现是在深搜过程中的一个剪枝处忘记调整全局变量的值,,,低级错误要引以为戒!!

for (int i = 0; i <= cur; i++) {
a[x] += i;
if (a[x] < a[x-1]) {
a[x] -= i; // 考试时此处直接写成了continue,忘记还原a数组
continue;
}
dfs(x + 1, cur - i);
a[x] -= i;
}

T2乱搞题,考试时连样例都没过,但是,输出时忘记写("Case"),,虽然结果都是零分,但是这种低级错误不能容忍!!

T3送分题,想出来了是树状数组,但是还是被最后三个点卡了读入常数。。Pascal直接写read就能A,然而C++的scanf就被卡了常数,,改成手写读入后AC,收了一个教训,当数据量较大时要考虑手写读入


官方题解:

a:
看到200的数据范围,看到个数和总和的范围的限制,我想所有人都会想到dp吧。。。
但是他说能凑成1~M的所有数字,这个略难满足
我们来看一个结论 假设我们选出的数字从小到大排序后,是a[], sum[]为a的前缀和
那么只要sum[N] = M 而且 a[i + 1] <= sum[i] + 1 那么就能满足1~M的所有数字
证明
充分性
可以数学归纳法证明
首先第一项a[1]必然等于1 他能凑成1~sum[1]的所有数字
假设前i项能组成sum[i]的所有数字,那么加上第i+1项后就能凑出a[i + 1] ~ a[i + 1] + sum[i]
因为a[i+ 1] <= sum[i] + 1 所以可以凑出1~a[i + 1] + sum[i] 也就是 1~sum[i+1]
必要性
可以想到如果不满足,那么起码sum[i] + 1就不能凑出来
这样就可以DP了
用f[i][j][k]代表前i个数字,和为j,是用小于等于k的数字凑出来的 即可
空间限制就用滚动数组吧
b:
如果只是单纯想如何组织这些边去形成一个方差最小的生成树,那是很困难的,至少我没有什么很好的解决办法
但是如果我们假定知道了平均值,想得出一个方差最小的生成树呢?
显然,边权尽量靠近平均值即可,而又要是棵树,那么明显只要用我们最常用的求最小生成树的方法即可.
那么平均值就可以直接枚举了,注意算出是哪些边之后要重新算出平均值
如果直接暴力枚举,时间复杂度是O(N*50*MlogM) 其中,N*M是平均值的个数。
可以发现这样可能超时
MlogM的最小生成树的算法已经无法再降,我们考虑平均值的枚举
首先一个很重要的条件,权值都是整数,那么如果你枚举的平均值x在[p, p+1]中,那么其实只有p.25 和 p.75 是需要枚举的
(自己想想为什么)
那么复杂度就是50*MlogM
c:
送分树状数组
把一个牌后面去就在最后加1,之前的位置减1,问她前面有多少人直接求前缀和吧

解题报告:

T3:

树状数组裸题,数组a记录每个人当前所在的位置,数组C为0/1数组记录当前位置是否有人,利用树状数组维护前缀和,每次查询直接查询前缀和,每次修改x时先change当前位置-1,change目标位置+1,再修改a数组更新x的位置。注意数组大小

#include <cstdio>
#include <cstring>
#include <algorithm> const int maxn = 4000500; int a[maxn]; // a[x] the cur location of x
int c[maxn];
int tot;
int n, m;
int k;
int x;
char s; inline int lowbit(int x) {
return (x & (-x));
} void change(int x, int z) {
while (x <= k) {
c[x] += z;
x = x + (x & (-x));
}
} int xfind(int x) {
int ans = 0;
while (x > 0) {
ans += c[x];
x = x - (x & (-x));
}
return (ans);
} int readint(void) {
s = getchar();
while (s < '0' && s > '9') s = getchar();
int x;
while (s >= '0' && s <= '9') {
x = x * 10;
x += (int) (s - '0');
s = getchar();
}
return x;
} int main () {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
n = readint();
m = readint();
k = n + m;
for (int i = 1; i <= n; i++) {
a[i] = n - i + 1;
change(i, 1);
}
tot = n;
for (int i = 1; i <= m; i++) {
x = readint();
printf("%d\n", n - xfind(a[x]));
change(a[x], -1);
tot++;
a[x] = tot;
change(a[x], 1);
}
return 0;
}

T1:

dp题目(最近为什么这么多dp题目)首先考虑一个性质

假设当前已经选择了i-1个砝码,它们能够满足题意的最大质量为j,那么对于第i个砝码,其质量为a[i],如果a[i] <= j + 1,显然它能够达到j + a[i],(可以尝试举个栗子验证),而反之如果a[i] > j显然j + 1就已经不能满足。由此可推得转移时保证合法性的条件

设dp[i][j][k]表示当前取到第i个砝码,当前的最大满足条件为j,当前的最大砝码为k,

dp[i][j][k] = dp[i][j][k-1] + dp[i-1][j-k][k] (当i,j,k满足题意时)

貌似出题人是打算卡一下空间放滚动数组,不过,,好像并没有用上,,

#include <cstdio>
#include <cstring>
#include <algorithm> const int maxn = 200 + 10;
const long long mod = 4294967296ll;
long long dp[maxn][maxn][maxn];
int T; bool check(int i, int j, int k) {
if (k > (j - i + 1)) return 1;
if (j % 2 == 1) j = (j >> 1) + 1;
else j = j >> 1;
if (k > j) return 1;
return 0;
} int main () {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
scanf("%d", &T);
for (int i = 1; i <= 200; i++)
dp[1][1][i] = 1;
for (int i = 2; i <= 200; i++)
for (int j = 2; j <= 200; j++) {
if (i > j) continue;
for (int k = 1; k <= 200; k++) {
dp[i][j][k] = dp[i][j][k-1];
if (check(i, j, k)) continue;
dp[i][j][k] = (dp[i][j][k] + dp[i-1][j-k][k]) % mod;
}
}
int n, m;
while (T--) {
scanf("%d %d", &n, &m);
printf("%I64d\n", (dp[n][m][m] % mod + mod) % mod);
} return 0;
}

T2

乱搞题,题目中要求求方差最小的生成树,看起来比较无从下手,那么结合方差的性质可知,如果加入的边边权差尽量小,方差一定相应变小,这样就将方差问题转化为排序问题。之后考虑题目的数据范围,可以发现题目中的边的边权均较小,由此可以直接枚举平均值,每次按照abs(p[x].val - w_average)来排序,加入直到形成生成树,求出此时方差并更新答案。

注意,由于枚举平均值可能带来的精度问题,建议转而枚举边的总值

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdlib>
const int maxn = 1000 + 10;
const int maxm = 10000 + 10;
struct data {
int from;
int to;
int val;
};
data p[maxm];
int tim;
int n, m;
int minw, maxw;
bool flag[maxn];
double t_average;
double fc;
double ans = 0x7fffffff;
int father[maxn]; int getfather(int x) {
if (father[x] == x) return (x);
return (father[x] = getfather(father[x]));
} bool cmp1 (data aa, data bb) {
return (aa.val < bb.val);
} bool cmp2(data aa, data bb) {
double a1 = (double) aa.val;
double a2 = (double) bb.val;
a1 = fabs(a1 - t_average);
a2 = fabs(a2 - t_average);
return (a1 < a2);
} int main () {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
while (scanf("%d %d", &n, &m) == 2 && n && m) {
tim++;
printf("Case %d: ", tim);
for (int i = 1; i <= m; i++) scanf("%d %d %d", &p[i].from, &p[i].to, &p[i].val);
std :: sort(p + 1, p + m + 1, cmp1);
for (int i = 1; i < n; i++) {
minw += p[i].val;
maxw += p[m - i + 1].val;
}
for (int k = minw; k <= maxw; k++) {
memset(flag, 0, sizeof(flag));
for (int j = 1; j <= n; j++ ) father[j] = j;
t_average = (double) k / (double) (n-1);
std :: sort(p + 1, p + m + 1, cmp2);
int t_sumw = 0;
for (int i = 1; i <= m; i++) {
int fx = getfather(p[i].from);
int fy = getfather(p[i].to);
if (fx != fy) {
father[fx] = fy;
flag[i] = 1;
t_sumw += p[i].val;
}
}
if (t_sumw == k) {
fc = 0;
for (int i = 1; i <= m; i++)
if (flag[i]) fc += ((double)p[i].val - t_average) * ((double)p[i].val - t_average);
if (fc < ans) ans = fc;
}
}
ans = ans / (double) (n-1);
printf("%.2lf\n", ans);
}
}

2016 10 28考试 dp 乱搞 树状数组的更多相关文章

  1. HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca

    Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...

  2. 【题解】ARC101F Robots and Exits(DP转格路+树状数组优化DP)

    [题解]ARC101F Robots and Exits(DP转格路+树状数组优化DP) 先删去所有只能进入一个洞的机器人,这对答案没有贡献 考虑一个机器人只能进入两个洞,且真正的限制条件是操作的前缀 ...

  3. [BZOJ2244]:拦截导弹(DP+CDQ分治+树状数组)

    题目传送门 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高于 ...

  4. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  5. 2016北京网络赛 hihocoder 1391 Countries 树状数组

    Countries   描述 There are two antagonistic countries, country A and country B. They are in a war, and ...

  6. CodeForces 602E【概率DP】【树状数组优化】

    题意:有n个人进行m次比赛,每次比赛有一个排名,最后的排名是把所有排名都加起来然后找到比自己的分数绝对小的人数加一就是最终排名. 给了其中一个人的所有比赛的名次.求这个人最终排名的期望. 思路: 渣渣 ...

  7. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

  8. bzoj4361:isn(dp+容斥+树状数组)

    题面 darkbzoj 题解 \(g[i]\)表示长度为\(i\)的非降序列的个数 那么, \[ ans = \sum_{i=1}^{n}g[i]*(n-i)!-g[i+1]*(n-i-1)!*(i+ ...

  9. hdu6078 Wavel Sequence dp+二维树状数组

    //#pragma comment(linker, "/STACK:102400000,102400000") /** 题目:hdu6078 Wavel Sequence 链接:h ...

随机推荐

  1. 2015 Multi-University Training Contest 10 hdu 5406 CRB and Apple

    CRB and Apple Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  2. Hadoop(2)_机器信息分布表

    1.分布式环境搭建 采用4台安装Linux环境的机器来构建一个小规模的分布式集群. 图1 集群的架构 其中有一台机器是Master节点,即名称节点,另外三台是Slaver节点,即数据节点.这四台机器彼 ...

  3. 数据库连接池dataesoruce pool深入理解

    8.数据库连接池的connection都是长连接的,以方便多次调用,多人连续使用.dataSourcePool9.数据库连接池中的连接,是在你用完之后,返回给数据库连接池的,并不是close()掉,而 ...

  4. iOS相册实现与AssetsLibrary框架使用

    概述 在iOS中如果想要获取手机相册里面的图片或者视频的话就要用到系统自带的AssetsLibrary框架,AssetsLibrary.framework中包含以下文件 #import <Ass ...

  5. Zookeeper源代码编译为Eclipseproject(win7下Ant编译)

    为了深入学习ZooKeeper源代码,首先就想到将其导入到Eclispe中,所以要先将其编译为Eclispeproject. 1.什么是Ant??? Apache Ant™ Apache Ant is ...

  6. Codeforces Round #284 (Div. 1) B. Name That Tune(概率DP)(难)

    B. Name That Tune time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  7. the rendering library is more recent than your version of android studio

    近期更新了自己Android Studio中的SDK到最新版本号,AS的一部分配置改动了. 然后 在打开布局文件的时候 会出现 渲染错误 Rendering problem the rendering ...

  8. 多线程的join和interrupt

    你可以在一个线程1里添加线程2对象thread的join方法来让线程1处于等待的状态 ,同时也可以调用thread.interrupt()来打断等待状态,此处注意 interrupt应在线程1开启st ...

  9. 去哪网实习总结:JavaWeb中文传參乱码问题的解决(JavaWeb)

    本来是以做数据挖掘的目的进去哪网的.结构却成了系统开发... 只是还是比較认真的做了三个月.老师非常认同我的工作态度和成果... 实习立即就要结束了,总结一下几点之前没有注意过的变成习惯和问题,分享给 ...

  10. File and Folder Permissions

    https://msdn.microsoft.com/en-us/library/bb727008.aspx On NTFS volumes, you can set security permiss ...