题面.pdf

T1:
通过打表发现,从一个点出发只有距离为1,2,3,5,6,9,10,13,17的点才不能到达;

那么我们转移的时候只有距离在20以内才不一定能直接转移,那么我们离散化之后;

对于每一个矿往前for 20个,然后特判距离是否合法进行转移即可;

//MADE BY QT666
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=200050;
int tot,hsh[N],a[N],v[N],b[N],n,m;
int dp[N];
bool check(int x){
if(x==1||x==2||x==3||x==5||x==6||x==9||x==10||x==13||x==17) return 0;
return 1;
}
int main(){
freopen("mining.in","r",stdin);
freopen("mining.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i],&b[i]);
hsh[++tot]=b[i];
}
sort(hsh+1,hsh+1+tot);tot=unique(hsh+1,hsh+1+tot)-hsh-1;
for(int i=1;i<=n;i++){
b[i]=lower_bound(hsh+1,hsh+1+tot,b[i])-hsh;
v[b[i]]+=a[i];
}
for(int i=1;i<=tot;i++) dp[i]=-(1e9+1);
for(int i=1;i<=tot;i++){
for(int j=max(0,i-20);j<i;j++){
if(check(hsh[i]-hsh[j])) dp[i]=max(dp[i],dp[j]+v[i]);
}
}
int ans=0;
for(int i=1;i<=tot;i++) /*cout<<hsh[i]<<' '<<dp[i]<<endl,*/ans=max(ans,dp[i]);
printf("%d\n",ans);
return 0;
}

T2:

首先因为方差只会越变越大,所以可以加剪枝进行搜索,但是双向搜索还是无法100%;

考虑到把答案的式子拆开变为(n+m-1)*∑ai^2-sum*sum,我们发现答案只和sum和∑ai^2这两个量有关;

那么我们可以用一种很套路的动态规划,在状态中开一维表示其中一个量,然后用dp的转移过程中,求出该状态下另一个量的最优;

那么我们设dp[i][j][k],表示到i行j列,sum为k的,∑ai^2的最小值,然后转移就是很simple了,最后枚举第三维的状态,然后算出该状态下的最优值;

//MADE BY QT666
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=2000;
int a[40][40],dp[40][40][N],T,n,m;
int main(){
freopen("matrix.in","r",stdin);
freopen("matrix.out","w",stdout);
scanf("%d",&T);
while(T--){
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
}
memset(dp,127/3,sizeof(dp));int sum=30*(n+m-1);
dp[1][1][a[1][1]]=a[1][1]*a[1][1];
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int k=0;k<=sum;k++){
if(dp[i][j][k]==dp[0][0][0]) continue;
if(i+1<=n) dp[i+1][j][k+a[i+1][j]]=min(dp[i+1][j][k+a[i+1][j]],dp[i][j][k]+a[i+1][j]*a[i+1][j]);
if(j+1<=m) dp[i][j+1][k+a[i][j+1]]=min(dp[i][j+1][k+a[i][j+1]],dp[i][j][k]+a[i][j+1]*a[i][j+1]);
}
}
}
int ans=dp[0][0][0];
for(int i=1;i<=sum;i++){
if(dp[n][m][i]==dp[0][0][0]) continue;
ans=min(ans,(n+m-1)*dp[n][m][i]-i*i);
}
printf("%d\n",ans);
}
}

T3:

首先M=0的做法,就是以父亲来转移,ans[x]=ans[fa[x]-size[x]*w+(n-size[x])*w;

然我们考虑M不为0的情况,因为M很小,二进制中只有4位,那么我们把一个二进制数分成两边来计算;

后4位中的是要受xor影响的,但是前面都是不用管xor的影响的;

那么我们对于一个x开两个数组,sum[x]表示除开后4位的数值,(最后算答案的时候<<4),f[x][i](i=0~15),表示跟x距离为i的点的数量;

那么我们考虑如何合并,其实相当于模拟二进制进位运算;

设父亲为 x+y,儿子为a+b,那么合并后相当于变为,((x+y)+(a+b)/16)+(a+b)%16;

也就是在加法的过程中处理进位,在具体处理过程中,我们考虑边的贡献来进行合并,因为相当于是儿子中所有距离要+w;

那么我们先考虑这个东西对前面的贡献,即(w/16)*size[son];

然后在考虑这个东西堆后面四位的贡献,即枚举0-15,+w,然后处理进位;

这样第一遍dfs就解决了子树内的问题,然后我们考虑父亲对儿子的贡献;

这里有一个常用技巧,就是用一个数组存下父亲除去该儿子的子树的答案,然后就可以“颠倒”父子关系,把父亲当儿子进行处理,处理方法就和第一遍dfs一样;

最后处理答案的时候就是前面的答案<<4,然后再把后面的0-15 xor m再乘以数量加入答案;

//MADE BY QT666
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=200050;
int dp[N][16],c[16],sum[N];
int head[N],to[N],nxt[N],v[N],cnt,dis[N],size[N],ans[N],n,m;
void lnk(int x,int y,int z){
to[++cnt]=y,nxt[cnt]=head[x],v[cnt]=z,head[x]=cnt;
to[++cnt]=x,nxt[cnt]=head[y],v[cnt]=z,head[y]=cnt;
}
void dfs1(int x,int f){
dp[x][0]=1;size[x]=1;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];if(y==f) continue;
dfs1(y,x);int w=v[i];
sum[x]+=sum[y]+(w/16)*size[y];
int g=w%16;
for(int j=0;j<=15;j++){
dp[x][(j+g)%16]+=dp[y][j];
sum[x]+=dp[y][j]*((j+g)/16);
}
size[x]+=size[y];
}
}
void dfs2(int x,int f){
ans[x]=sum[x]<<4;
for(int i=0;i<=15;i++) ans[x]+=(i^m)*dp[x][i];
for(int i=head[x];i;i=nxt[i]){
int y=to[i];if(y==f) continue;
int w=v[i],ret=sum[x]-sum[y]-(w/16)*size[y],g=w%16;
memset(c,0,sizeof(c));
for(int j=0;j<=15;j++){
ret-=dp[y][j]*((j+g)/16);
c[(j+g)%16]=dp[x][(j+g)%16]-dp[y][j];
}
ret+=(w/16)*(n-size[y]);
for(int j=0;j<=15;j++){
dp[y][(j+g)%16]+=c[j];
sum[y]+=c[j]*((j+g)/16);
}
sum[y]+=ret;dfs2(y,x);
}
}
int main(){
freopen("warehouse.in","r",stdin);
freopen("warehouse.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++){
int x,y,z;scanf("%d%d%d",&x,&y,&z);lnk(x,y,z);
}
dfs1(1,0);dfs2(1,0);
for(int i=1;i<=n;i++) printf("%d\n",ans[i]-m);
return 0;
}

9.11 test的更多相关文章

  1. 地区sql

    /*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...

  2. WinForm 天猫2013双11自动抢红包【源码下载】

    1. 正确获取红包流程 2. 软件介绍 2.1 效果图: 2.2 功能介绍 2.2.1 账号登录 页面开始时,会载入这个网站:https://login.taobao.com/member/login ...

  3. C++11特性——变量部分(using类型别名、constexpr常量表达式、auto类型推断、nullptr空指针等)

    #include <iostream> using namespace std; int main() { using cullptr = const unsigned long long ...

  4. CSS垂直居中的11种实现方式

    今天是邓呆呆球衣退役的日子,在这个颇具纪念意义的日子里我写下自己的第一篇博客,还望前辈们多多提携,多多指教! 接下来,就进入正文,来说说关于垂直居中的事.(以下这11种垂直居中的实现方式均为笔者在日常 ...

  5. C++ 11 多线程--线程管理

    说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...

  6. CSharpGL(11)用C#直接编写GLSL程序

    CSharpGL(11)用C#直接编写GLSL程序 +BIT祝威+悄悄在此留下版了个权的信息说: 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharp ...

  7. ABP(现代ASP.NET样板开发框架)系列之11、ABP领域层——仓储(Repositories)

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之11.ABP领域层——仓储(Repositories) ABP是“ASP.NET Boilerplate Proj ...

  8. C++11 shared_ptr 智能指针 的使用,避免内存泄露

    多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用, 在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃, 所以为 ...

  9. C++11网络编程

    Handy是一个简洁优雅的C++11网络库,适用于linux与Mac平台.十行代码即可完成一个完整的网络服务器. 下面是echo服务器的代码: #include <handy/handy.h&g ...

  10. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(11)-系统日志和异常的处理①

    系列目录 系统需要越来越自动化,我们需要引入日志记录和异常捕获管理员的操作记录需要被记录,看出哪些模块是频繁操作,分析哪些是不必要的功能,哪些是需要被优化的.系统的异常需要被捕获,而不是将系统出错显示 ...

随机推荐

  1. git的CentOS服务端安装和windows客户端的使用

    git的CentOS服务端安装和windows客户端的使用 此教程以 搬瓦工vps CentOS 6 x64 的系统为环境,搭建 git 服务端.windows 7 系统为客户端. git客户端 在W ...

  2. poj 3111 K Best 最大化平均值 二分思想

    poj 3111 K Best 最大化平均值 二分思想 题目链接: http://poj.org/problem?id=3111 思路: 挑战程序竞赛书上讲的很好,下面的解释也基本来源于此书 设定条件 ...

  3. oracle和mysql几点差异对比

    Oracle与mysql差异性总结 之前有个项目是用oracle数据库进行开发,需要把数据库改成mysql,遇到了一些地方需要注意的,就简单记了下来. 备注: 再把oracle转成mysql的时候,表 ...

  4. 直播一:H.264编码基础知识详解

    一.编码基础概念 1.为什么要进行视频编码? 视频是由一帧帧图像组成,就如常见的gif图片,如果打开一张gif图片,可以发现里面是由很多张图片组成.一般视频为了不让观众感觉到卡顿,一秒钟至少需要16帧 ...

  5. win10 mysql详尽安装教程

    我的电脑系统是win10 64位系统 我安装mysql不下5次,装好了又卸,卸了又装,看了老多篇文章和博客,非常感谢博主的无私帮助,以下是这些博主的文章: https://www.cnblogs.co ...

  6. 关于C#中函数的认识

    对于C#语言中的函数,大概分之为函数的声明及其调用. 函数的声明: 1.函数的声明是指给一段代码取名称. 2.函数的声明位置必须在类中. 3.函数声明的语法: 函数声明的语法:static void ...

  7. ListView与Adapter笔记:ZrcListView

    怕自己说的不清不楚,先来一个郭神的文章镇楼:http://blog.csdn.net/guolin_blog/article/details/44996879 github:https://githu ...

  8. 动态规划-迷宫-百度之星-Labyrinth

    Labyrinth Problem Description 度度熊是一仅仅喜欢探险的熊.一次偶然落进了一个m*n矩阵的迷宫,该迷宫仅仅能从矩阵左上角第一个方格開始走,仅仅有走到右上角的第一个格子才算走 ...

  9. 在无人值守程序(服务)中调用Microsoft Graph

    作者:陈希章 发表于 2017年5月31日 什么是无人值守程序(服务) 我在此前用了几篇文章分别介绍了在桌面应用程序(控制台),Web应用程序(ASP.NET MVC),以及PowerSehll脚本中 ...

  10. 【Sqlsever系列】日期和时间

    1   概述 本文将集合MSDN简要概述Sqlserver中日期和时间函数. 2   具体内容 2.1  date and time data types 2.2  日期和时间功能 3   参考文献 ...