A. 小奇挖矿2

显然的O(m)dp:$f[i]=max(f[i-4],f[i-7])+a[i]$,当然你要保证i,i-4,i-7都能到达

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define re register
using namespace std;
const int MAXN=1e7+5;
int n,m,a[MAXN],b[MAXN],ans=0,f[MAXN];
signed main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i],&b[i]);
f[b[i]]+=a[i];
}
for(int i=0;i<=3;i++) f[i]=-1;
for(int i=5;i<=6;i++) f[i]=-1;
ans=max(f[4],f[7]);
for(int i=8;i<=m;i++){
if(f[i-4]==-1&&f[i-7]==-1){
f[i]=-1;
continue;
}
f[i]+=max(f[i-4],f[i-7]);
ans=max(ans,f[i]);
}
printf("%d\n",ans);
return 0;
}

然后我们优化,我们发现如果两点之间的距离超过18就一定能到达,所以我们把距离压缩一下

具体为什么你需要做一下NOIP2017小凯的疑惑

然后就AC了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define re register
using namespace std;
const int MAXN=2e6+5;
int n,m,a[MAXN],b[MAXN],ans=0,f[MAXN];
struct node{
int a,b;
friend bool operator < (node x,node y){
return x.b==y.b?x.a<y.a:x.b<y.b;
}
}mine[MAXN];
signed main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d%d",&mine[i].a,&mine[i].b);
sort(mine+1,mine+n+1);
for(int i=1;i<=n;i++){
if(mine[i].b-mine[i-1].b>17)
a[i]=mine[i].a,b[i]=b[i-1]+18;
else a[i]=mine[i].a,b[i]=b[i-1]+(mine[i].b-mine[i-1].b);
}
for(int i=1;i<=n;i++) f[b[i]]+=a[i];
for(int i=0;i<=3;i++) f[i]=-1;
for(int i=5;i<=6;i++) f[i]=-1;
m=b[n];
ans=max(f[4],f[7]);
for(int i=8;i<=m;i++){
if(f[i-4]==-1&&f[i-7]==-1){
f[i]=-1;
continue;
}
f[i]+=max(f[i-4],f[i-7]);
ans=max(ans,f[i]);
}
printf("%d\n",ans);
return 0;
}

还有一种解决方法:

将所有矿物排序,f[i]为到第i个矿体能获得的最大原矿数,那么f[i]=max{f[j]}+x[i],其中,i-j满足能拆分成4和7。

这样dp需要n2的复杂度,但是我们发现,相距超过17的一定可达,那么不超过17的范围内暴力,超过17的取个最大值即可,复杂度O(n)

from skyh:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int N=1e5+10;
map<int,int> mp;
int n,m,ans,cnt;
int dp[N],mx[N];
bool ok[20]={1,0,0,0,1,0,0,1,1,0,0,1,1,0,1,1,1,0};//0 4 7 8 11 12 14 15 16 >17
inline int read(register int x=0,register char ch=getchar(),bool ff=0){
while(!isdigit(ch)) ff=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return ff?-x:x;
}
struct node{
int val,pos;
friend bool operator < (const node &a,const node &b){
return a.pos<b.pos;
}
}k[N];
int main(){
//freopen("x.in","r",stdin);
//freopen("me.out","w",stdout);
n=read(); m=read();
for(int i=1,v,p,o;i<=n;++i){
v=read(),p=read();
if(!mp[p]) mp[p]=++cnt;
o=mp[p]; k[o].pos=p; k[o].val+=v;
}
sort(k+1,k+cnt+1);
memset(dp,-0x3f,sizeof(dp));
dp[0]=0;
for(int i=1;i<=cnt;++i){
for(int j=i-1;~j;--j){
if(k[i].pos-k[j].pos<=17&&ok[k[i].pos-k[j].pos]) dp[i]=max(dp[i],dp[j]+k[i].val);
if(k[i].pos-k[j].pos>17){
dp[i]=max(dp[i],mx[j]+k[i].val);
break;
}
}
ans=max(ans,dp[i]);
mx[i]=max(mx[i-1],dp[i]);
}
printf("%d\n",ans);
return 0;
}

B:小奇的矩阵(matrix)

平均数这玩意显然可拆:令$sum=\sum A_i$,$sqr=\sum A_{i}^{2}$

$Aavg=\frac{sum}{n+m-1}$

所以:原式=$(n+m-1)*sqr-sum^2$,推一下就能推出来

然后。。。我竟然去想了搜索!

正解dp:设$f[s][i][j]$表示到了点(i,j),总和为s时的最小sqr值

所以f[s][i][j]=min(f[s-a[i][j]][i][j-1]+a[i][j]*a[i][j],f[s-a[i][j]][i-1][j]+a[i][j]*a[i][j]);

然后就做出来了

#include<iostream>
#include<cstdio>
#include<cstring>
#define inf 0x3f3f3f3f
#define re register
using namespace std;
int t,n,m,a[35][35],ans,f[1805][35][35];
signed main(){
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(re int i=1;i<=n;i++)
for(re int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
ans=inf;
memset(f,0x3f,sizeof(f));
f[a[1][1]][1][1]=a[1][1]*a[1][1];
for(re int i=1;i<=n;i++){
for(re int j=1;j<=m;j++)
for(re int k=1;k<=1800;k++){
if(k<a[i][j]) continue;
f[k][i][j]=min(f[k][i][j],f[k-a[i][j]][i-1][j]+a[i][j]*a[i][j]);
f[k][i][j]=min(f[k][i][j],f[k-a[i][j]][i][j-1]+a[i][j]*a[i][j]);
}
}
for(re int k=1;k<=1800;k++){
if(f[k][n][m]>=inf) continue;
ans=min(ans,(n+m-1)*f[k][n][m]-k*k);
}
printf("%d\n",ans);
}
return 0;
}

C:小奇的仓库(warehouse)

美妙的换根dp

设f[i][j]表示i到其他点,后4位状态为j的路径数

f[x][0]=1

f[x][(j+w)%16]+=f[y][j]

f[y][(j+w)%16]+=(f[x][j]-f[y][((j-w)%16+16)%16])

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#define MAXN 100005
#define int long long
using namespace std;
int n,m,ans=0;
int to[MAXN<<1],nxt[MAXN<<1],pre[MAXN],cnt=0,w[MAXN<<1];
void add(int u,int v,int val){
cnt++,to[cnt]=v,w[cnt]=val,nxt[cnt]=pre[u],pre[u]=cnt;
}
int g[MAXN],f[MAXN][17],t[MAXN][17];
void DFS(int x,int fa){
f[x][0]=1;
for(int i=pre[x];i;i=nxt[i]){
int y=to[i];
if(y==fa) continue;
DFS(y,x);
g[x]+=g[y];
for(int j=0;j<16;j++){
f[x][(j+w[i])&15]+=f[y][j];
g[x]+=f[y][j]*w[i];
}
}
}
void dfs(int x,int fa){
for(int i=pre[x];i;i=nxt[i]){
int y=to[i];
if(y==fa) continue;
int size=0;
for(int j=0;j<16;j++){
t[y][(j+w[i])&15]+=f[x][j]-f[y][((j-w[i])&15+16)&15];
size+=f[y][j];
}
g[y]=g[x]+(n-size*2)*w[i];
for(int j=0;j<16;j++) f[y][j]+=t[y][j];
dfs(y,x);
}
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=1,u,v,val;i<n;i++){
scanf("%lld%lld%lld",&u,&v,&val);
add(u,v,val),add(v,u,val);
}
DFS(1,0);
dfs(1,0);
for(int i=1;i<=n;i++){
for(int j=0;j<16;j++){
int k=j^m;
g[i]+=(k-j)*f[i][j];
}
printf("%lld\n",g[i]-m);
}
return 0;
}

HZOI20190820模拟27题解的更多相关文章

  1. [CQOI2012]模拟工厂 题解(搜索+贪心)

    [CQOI2012]模拟工厂 题解(搜索+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327574 链接题目地址:洛谷P3161 BZOJ P26 ...

  2. noip模拟27[妹子图·腿·腰](fengwu半仙的妹子们)

    \(noip模拟27\;solutions\) 这次吧,我本来以为我能切掉两个题,结果呢??只切掉了一个 不过,隔壁Varuxn也以为能切两个,可惜了,他一个都没切...... 确实他分比我高一点,但 ...

  3. 2021.7.29考试总结[NOIP模拟27]

    T1 牛半仙的妹子图 做法挺多的,可以最小生成树或者最短路,复杂度O(cq),c是颜色数. 我考场上想到了原来做过的一道题影子,就用了并查集,把边权排序后一个个插入,记录权值的前缀和,复杂度mlogm ...

  4. NOIP第7场模拟赛题解

    NOIP模拟赛第7场题解: 题解见:http://www.cqoi.net:2012/JudgeOnline/problemset.php?page=13 题号为2221-2224. 1.car 边界 ...

  5. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  6. HGOI NOIP模拟4 题解

    NOIP国庆模拟赛Day5 题解 T1 马里奥 题目描述 马里奥将要参加 NOIP 了,他现在在一片大陆上,这个大陆上有着许多浮空岛,并且其中一座浮空岛上有一个传送门,马里奥想要到达传送门从而前往 N ...

  7. 10.8 wtx模拟题题解

    填坑 orz w_x_c_q w_x_c_q的模拟赛(150pts,炸了) money 题目背景: 王小呆又陷入自己的梦里.(活在梦里...) 题目描述: 王小呆是一个有梦想的小菜鸡,那就是赚好多好多 ...

  8. [NOIP模拟13]题解

    A.矩阵游戏 其实挺水的? 考场上根本没有管出题人的疯狂暗示(诶这出题人有毛病吧这么简单的东西写一大堆柿子),而且推公式能力近乎没有,所以死掉了. 很显然乘法有交换率结合率所以操作顺序对最终结果没什么 ...

  9. 「题解」NOIP模拟测试题解乱写II(36)

    毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...

随机推荐

  1. hdu多校第二场 1005 (hdu6595) Everything Is Generated In Equal Probability

    题意: 给定一个N,随机从[1,N]里产生一个n,然后随机产生一个n个数的全排列,求出n的逆序数对的数量,加到cnt里,然后随机地取出这个全排列中的一个非连续子序列(注意这个子序列可以是原序列),再求 ...

  2. EXCEL函数常用技巧浅析

    EXCEL函数常用技巧浅析 EXCEL函数是一门趣味性非常大的游戏,此贴内容基本上为总结前人经验而来.废话不多说,我们现在走入正题. 一:判断数值奇偶性 1.1  ISODD(number) 判断一个 ...

  3. 16.ajax_case06

    # 抓取华尔街见闻实时快讯 # https://wallstreetcn.com/live/global?from=navbar import requests import json header ...

  4. 初识OpenCV-Python - 005: 识别视频中的蓝色

    此次主要学习了如何将BGR转成HSV,主要用到cv2.cvtColor()和cv2.inRange()函数来识别视频中的蓝色物体. code: import cv2import numpy as np ...

  5. 在使用python语言的open函数时,提示错误OSError: [Errno 22] Invalid argument: ‘文件路径’

    如题,在使用python语言的open函数时,提示错误OSError: [Errno 22] Invalid argument: '文件路径',在查阅了大量资料后也得到了一些解决方案,但是这些解决方案 ...

  6. 分析Hive表和分区的统计信息(Statistics)

    类似于Oracle的分析表,Hive中也提供了分析表和分区的功能,通过自动和手动分析Hive表,将Hive表的一些统计信息存储到元数据中. 表和分区的统计信息主要包括:行数.文件数.原始数据大小.所占 ...

  7. 关于jar包启动遇到的问题

    一.找不到propertites文件,错误如下 原因是打成的jar不包含classpath信息,需要运行时指定,命令为 -Xbootclasspath/a: 后缀在核心class搜索路径后面.常用! ...

  8. 洛谷P4514 上帝造题的七分钟

    P4514 上帝造题的七分钟 题目背景 裸体就意味着身体. 题目描述 "第一分钟,X说,要有矩阵,于是便有了一个里面写满了000的n×mn×mn×m矩阵. 第二分钟,L说,要能修改,于是便有 ...

  9. Algo: Dynamic programming

    Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...

  10. Java事件监听机制与观察者设计模式

    一. Java事件监听机制 1. 事件监听三要素: 事件源,事件对象,事件监听器 2. 三要素之间的关系:事件源注册事件监听器后,当事件源上发生某个动作时,事件源就会调用事件监听的一个方法,并将事件对 ...