A:Birthday

时间限制: 1 Sec  内存限制: 256 MB

题目描述

恬恬的生日临近了。宇扬给她准备了一个大蛋糕。

正如往常一样,宇扬在蛋糕上插了n支蜡烛,并把蛋糕分为m个区域。因为某种原因,他必须把第i根蜡烛插在第ai个区域或第bi个区域。区域之间是不相交的。宇扬在一个区域内同时摆放x支蜡烛就要花费x2的时间。宇扬布置蛋糕所用的总时间是他在每个区域花的时间的和。

宇扬想快些见到恬恬,你能告诉他布置蛋糕最少需要多少时间吗?

输入

第一行包含两个整数nm(1 ≤ n ≤ 50, 2 ≤ m ≤ 50)。

接下来n行,每行两个整数ai, bi(1 ≤ ai, bim)。

输出

一个整数表示答案.

样例输入

3 3
1 2
1 2
1 2

样例输出

5

唉,还是大佬的题解写的好,所以感谢wls大佬分享思路  Orz。。。

思路:考虑费用流时把每个part拆成n个点,选择第i个点的代表为放置i块蛋糕和(i - 1)块蛋糕的时间差,

这个时间差是递增的,因此在费用流的过程中必定会从小到大选择

具体建图:

左边n个点代表n个蛋糕,右边m * n个点代表m个part,每个part拆成n个点。源点向每个左边的点连一条流量1费用0的边,每个右边的点向汇点连一条流量1费用0的编。

每个蛋糕向可以放的两个part的所有点连边,连向第i个点的费用为i^2 - (i - 1)^2,流量为1。这样求最小费用流既为答案。

#include"bits/stdc++.h"
using namespace std;
#define M 1100
const int inf=0x7fffffff;
struct node{
int u,v,c,f,next; //C为花费,F为flow流量
}e[M*40];
int pre[M],dis[M],head[M],t;
int vis[M]; void add1(int u,int v,int c,int f){
e[t].u=u;
e[t].v=v;
e[t].c=c;
e[t].f=f;
e[t].next=head[u];
head[u]=t++;
} void add(int u,int v,int c,int f){
add1(u,v,c,f);
add1(v,u,-c,0); //反向边流量初始为零,如果走反向边费用正好和原边抵消
} int spfa(int s,int t){
int i,u,v;
queue<int>q;
q.push(s);
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre));
for(i=s;i<=t;i++)
dis[i]=inf;
dis[s]=0;
while(!q.empty()){
u=q.front();
q.pop();
for(i=head[u];i!=-1;i=e[i].next)
{
v=e[i].v;
if(e[i].f&&dis[v]>dis[u]+e[i].c) //找到一条最小费用流
{
dis[v]=dis[u]+e[i].c;
pre[v]=i; //记录路径
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
vis[u]=0;
}
if(dis[t]!=inf)
return 1;
return 0;
} void solve(int s,int t){
int ans=0,i,j;
int flow=0,cost=0; //总流量、总费用
while(spfa(s,t)){
int minf=inf;
for(i=pre[t];i!=-1;i=pre[e[i].u]){
if(e[i].f<minf)
minf=e[i].f;
}
flow+=minf; //该条路径的流量
for(i=pre[t];i!=-1;i=pre[e[i].u]){
j=i^1;
e[i].f-=minf;
e[j].f+=minf;
}
cost+=dis[t]*minf; //单位运费和乘以流量得费用
}
printf("%d\n",cost);
}
int main(){
int i,u,v,c,n,m;
while(scanf("%d%d",&n,&m)==2){
t=0;
memset(head,-1,sizeof(head));
for(i=1;i<=n;i++){
scanf("%d%d",&u,&v);
add(0,i,0,1);
add(i,u+n,0,1);
add(i,v+n,0,1);
}
for(int i=1 ; i<=m ; ++i){
for(int j=1 ; j<=99 ; j+=2){//99 = 2*50-1;
add(i+n,n+m+1,j,1);
}
}
solve(0,n+m+1);
}
return 0;
}

B: Board

时间限制: 1 Sec  内存限制: 256 MB

题目描述

恬恬有一个n × n的数组。她在用这个数组玩游戏:

开始时,数组中每一个元素都是0。

恬恬会做某些操作。在一次操作中,她可以将某一行的所有元素同时加上一个值,也可以将某一列的所有元素同时加上一个值。

在几次操作后,一个元素被隐藏了。你能帮助她回忆隐藏的数是几吗?

输入

第一行一个整数n(1 ≤ n ≤ 1000)。

接下来n行每行n个整数表示数组a

第(i + 1)行的第j个元素表示aijaij =  - 1或0 ≤ aij ≤ 10000)。 - 1表示隐藏的元素。

输出

仅一个整数表示答案。

样例输入

3
1 2 1
0 -1 0
0 1 0

样例输出

1

这题思路同样为wls大佬给出,Orz wls 。。。

把格子N染色,第i行第j列格子的颜色为(i + j) % N。那么每次操作时,必定是N种不同的颜色都有一格被操作到,

因此最后任何颜色格子的和必定是相等的。因此只需要记录每种颜色格子的和,

并算出缺失格子的颜色C,用其余颜色的和减去颜色C的和即可

#include<bits/stdc++.h>

using namespace std;
int arr[1010][1010];
int a[1010], b[1010]; int main()
{
int n;
while(~scanf("%d", &n)){
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
int maxn = 10010, x, y;
for(int i = 1; i <= n; i++) {
maxn = 10010;
for(int j = 1; j <= n; j++) {
scanf("%d", &arr[i][j]);
if(arr[i][j] != -1){
maxn = min(maxn, arr[i][j]);
}
if(arr[i][j] == -1) {
x = i;
y = j;
}
}
a[i] = maxn;
}
int maxm;
for(int i = 1; i <= n; i++) {
int maxm = 10010;
for(int j = 1; j <= n; j++) {
if(arr[j][i] != -1){
maxm = min(maxm, arr[j][i]);
}
}
b[i] = maxm;
}
if(x == 1 && y == 1)cout << (a[x] + b[y]) - max((a[x+1]+b[y] - arr[x+1][y]),(a[x]+b[y+1]-arr[x][y+1])) << endl;
else if(x==n && y==1)cout << (a[x] + b[y]) - max((a[x-1]+b[y] - arr[x-1][y]),(a[x]+b[y+1]-arr[x][y+1])) << endl;
else if(x==1&&y==n)cout << (a[x] + b[y]) - max((a[x]+b[y-1] - arr[x][y-1]),(a[x+1]+b[y]-arr[x+1][y])) << endl;
else if(x==n&&y==n)cout << (a[x] + b[y]) - max((a[x-1]+b[y] - arr[x-1][y]),(a[x]+b[y-1]-arr[x][y-1])) << endl;
else if(x==1)cout << (a[x] + b[y]) - (a[x+1]+b[y]-arr[x+1][y]) << endl;
else if(x==n)cout << (a[x] + b[y]) - (a[x-1]+b[y]-arr[x+1][y]) << endl;
else cout << (a[x] + b[y]) - (a[x+1]+b[y] - arr[x+1][y]) << endl;
}
return 0;
}

D: Growth

时间限制: 1 Sec  内存限制: 256 MB

题目描述

弱弱有两个属性ab,这两个属性初始的时候均为0,每一天他可以通过努力,让a涨1点或b涨1点。

为了激励弱弱努力学习,我们共有n种奖励,第i种奖励有xiyizi三种属性,若axibyi,则弱弱在接下来的每一天都可以得到zi的分数。

问m天以后弱弱最多能得到多少分数。

输入

第一行一个两个整数nm(1 ≤ n ≤ 1000,1 ≤ m ≤ 2000000000)。

接下来n行,每行三个整数xiyizi(1 ≤ xi, yi ≤ 1000000000,1 ≤ zi ≤ 1000000)。

输出

一行一个整数表示答案。

样例输入

2 4
2 1 10
1 2 20

样例输出

50

提示

在样例中,弱弱可以这样规划:第一天a涨1,第二天b涨1,第三天b涨1,第四天a涨1。

共获得0 + 0 + 20 + 30 = 50分。

Orz wls。。。

把奖励的x拿出来从小到大排序,得到x1,x2,...,xn。

把奖励的y拿出来从小到大排序,得到y1,y2,...,yn。

用v[i][j]表示a值到达xi,b值达到yi时接下来每天可以得到的奖励。

v[i][j] = v[i - 1][j] + v[i][j - 1] - v[i - 1][j - 1] + t[i][j]

其中t[i][j]为满足x=i,y=j的奖励的总和。

用f[i][j]表示a值达到xi,b值达到yj时已经拿到的奖励的最大值。

f[i][j] + (x[i + 1] - x[i] - 1) * t[i][j] + t[i + 1][j] -> f[i + 1][j]

f[i][j] + (y[j + 1] - y[j] - 1) * t[i][j] + t[i][j + 1] -> f[i][j + 1]

最后统计一下答案就可以了。

不过这题有一个离散化不好写,我也是借鉴大佬的写法,

#include<bits/stdc++.h>
using namespace std; #define ios1 ios::sync_with_stdio(0)
#define ios2 cin.tie(0)
#define ll long long
#define inf 0x7ffffffff
typedef pair<int, int> P;
map<P, int>mp;
set<int>sx, sy; const int maxn = 1200; int n, m;
int xx[maxn], yy[maxn];
ll dp[maxn][maxn], v[maxn][maxn];
int x[maxn], y[maxn], z[maxn]; int main() {
ios1; ios2;
while(cin >> n >> m) {
int xi = 1, yi = 1;
for(int i = 0; i < n; i++) {
cin >> x[i] >> y[i] >> z[i];
if(mp.count(P(x[i], y[i])) == 0)mp[P(x[i], y[i])] = z[i];
else mp[P(x[i], y[i])] += z[i];
if(sx.count(x[i]) == 0){sx.insert(x[i]);xx[xi++] = x[i];}
if(sy.count(y[i]) == 0){sy.insert(y[i]);yy[yi++] = y[i];}
}
sort(xx, xx + xi);
sort(yy, yy + yi);//离散化
memset(dp, 0, sizeof(dp));
memset(v, 0, sizeof(v));
for(int i = 1; i < xi; i++) {
for(int j = 1; j < yi; j++) {
if(mp.count(P(xx[i], yy[j])) == 0)v[i][j] = v[i-1][j] + v[i][j-1] - v[i-1][j-1];
else v[i][j] = v[i-1][j] + v[i][j-1] - v[i-1][j-1] + mp[P(xx[i], yy[j])];
}
}
for(int i = 0; i < xi; i++) {
for(int j = 0; j < yi; j++) {
dp[i+1][j] = max(dp[i+1][j], dp[i][j] + (xx[i+1] - xx[i] - 1) * v[i][j] + v[i+1][j]);
dp[i][j+1] = max(dp[i][j+1], dp[i][j] + (yy[j+1] - yy[j] - 1) * v[i][j] + v[i][j+1]);
}
}
ll ans = 0;
for(int i = 1; i < xi; i++) {
for(int j = 1; j < yi; j++) {
ll r = dp[i][j] + (m - xx[i] - yy[j]) * v[i][j];
ans = max(ans, r);
}
}
cout << ans << endl;
}
return 0;
}

CCPC-Wannafly Summer Camp #1(部分解题报告)的更多相关文章

  1. 2020 CCPC Wannafly Winter Camp Day1 C. 染色图

    2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...

  2. CCPC Wannafly Winter Camp Div2 部分题解

    Day 1, Div 2, Prob. B - 吃豆豆 题目大意 wls有一个\(n\)行\(m\)列的棋盘,对于第\(i\)行第\(j\)列的格子,每过\(T[i][j]\)秒会在上面出现一个糖果, ...

  3. 2020 CCPC Wannafly Winter Camp Day1 Div.1&amp F

    #include<bits/stdc++.h> #define forn(i, n) for (int i = 0; i < int(n); i++) #define fore(i, ...

  4. 2020 CCPC Wannafly Winter Camp Day1 - I. K小数查询(分块)

    题目链接:K小数查询 题意:给你一个长度为$n$序列$A$,有$m$个操作,操作分为两种: 输入$x,y,c$,表示对$i\in[x,y] $,令$A_{i}=min(A_{i},c)$ 输入$x,y ...

  5. 2020 CCPC Wannafly Winter Camp Day2-K-破忒头的匿名信

    题目传送门 sol:先通过AC自动机构建字典,用$dp[i]$表示长串前$i$位的最小代价,若有一个单词$s$是长串的前$i$项的后缀,那么可以用$dp[i - len(s)] + val(s)$转移 ...

  6. 2020 CCPC Wannafly Winter Camp Day1-F-乘法

    题目传送门 sol:二分答案$K$,算大于$K$的乘积有多少个.关键在于怎么算这个个数,官方题解上给出的复杂度是$O(nlogn)$,那么计算个数的复杂度是$O(n)$的.感觉写着有点困难,自己写了一 ...

  7. Mutual Training for Wannafly Union #1解题报告

    ---恢复内容开始--- q神等人组织的vjudge上的多校训练,题目基本上都来自于CF,#1是上周进行的,参加后感觉收获很多,因为上周准备期中比较忙,解题报告现在补上. 比赛地址(兼题目地址) A题 ...

  8. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

  9. 二模13day1解题报告

    二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...

  10. BZOJ 1051 最受欢迎的牛 解题报告

    题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4438  Solved: 2353[S ...

随机推荐

  1. ipad pro 为什么不行

    TalkingData公布的数据显示,iPad Pro在中国发行首月的销量仅为49 300台,而此前iPad Air 2发行首月后销量曾高达55.7万台.那么到底是什么原因,让这个被寄予厚望的iPad ...

  2. 后端基于方法的权限控制--Spirng-Security

    后端基于方法的权限控制--Spirng-Security 默认情况下, Spring Security 并不启用方法级的安全管控. 启用方法级的管控后, 可以针对不同的方法通过注解设置不同的访问条件: ...

  3. java根据经纬度查询门店地理位置-完美解决附近门店问题

    1.首先我们需要创建一个门店表如下: CREATE TABLE `app_store` ( `store_id` ) NOT NULL AUTO_INCREMENT COMMENT '发布id', ` ...

  4. java虚拟机学习笔记(四)---回收方法区

    Java虚拟机规范中规定不要求虚拟机在方法区实现垃圾收集,而且在方法区实现垃圾收集性价比确实很低.在堆中,尤其是新生代,一次垃圾收集可以回收75%-95%的空间,而永久代的垃圾回收效率远低于此. 永久 ...

  5. 超全的 Vue 开源项目合集,签收一下

    超全的 Vue 开源项目合集,签收一下 xiaoge2016 前端开发 1周前 作者:xiaoge2016 链接: https://my.oschina.net/u/3018050/blog/2049 ...

  6. 超实用,Linux中查看文本的小技巧

    日常开发中,我们经常需要在服务器上进行各种文本,日志的查看操作,本文主要对常用的文本,日志查看技巧进行了一番总结和归纳,方便大家收藏起来后续查看使用: tail命令查看日志信息 实时监控日志: tai ...

  7. 洛谷 P5367 【模板】康托展开(数论,树状数组)

    题目链接 https://www.luogu.org/problem/P5367 什么是康托展开 百度百科上是这样说的:   “康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩. ...

  8. MTFlexbox自动化埋点探索

    1. 背景 跨平台动态化技术是目前移动互联网领域的重点关注方向,它既能节约人力,又能实现业务快速上线的需求.经过十年的发展,美团App已经变成了一个承载众多业务的超级平台,众多的业务方对业务形态的快速 ...

  9. 从零开始一起学习SLAM | 用四元数插值来对齐IMU和图像帧

    视觉 Vs. IMU 小白:师兄,好久没见到你了啊,我最近在看IMU(Inertial Measurement Unit,惯性导航单元)相关的东西,正好有问题求助啊 师兄:又遇到啥问题啦? 小白:是这 ...

  10. Ng-Matero 0.1 发布了!

    Ng-Matero 0.1 终于发布了!周末折腾了两天,结果最后发版还是出了点意外,好在今天补了一版. 距离 Ng-Matero 发布第一版已经过去了一个多月,然后很颓废地休息了半个多月,最近项目的关 ...