题目大意:

给定一堆带颜色和高度的魔方

用两种颜色的魔方,一种颜色接一种颜色向上拼接搭建成一个高塔,求高塔的最长高度,以及将拼接的过程中对应的编号顺序输出

多种情况成立输出任意一种即可

这里首先要对颜色(c值)进行离散化,这样每种颜色都对应有一个编号

用一个响亮vec[i]来保存 编号 i 的颜色的高度值以及对应要输出时的序号 , 高度值由大到小保存,这个可以在一开始的魔方排序给c离散化的时候做到

拼接可以是两种颜色各有 len 个 , 或者一种为len , 一种为len+1

那么利用一个数组max_val [len] , sec_val[len]保存有len个颜色相同的魔方所能构建的最大和次大值

那么同时也要建立max_id[len] , sec_id[len]表示len个颜色相同的魔方所能构建的最大和次大值时对应的 颜色离散化后的标号

每次不断往向量中加入一个魔方的情况,加的同时就可以对上述的4个数组进行更新,因为 s 由大到小排列,那么加的时候始终得到的是当前颜色这个长度所能达到的最大

这样就可以max_val [len] , sec_val[len]来求最大值,中间找到最大值时,记录一些相关数据以便最后的输出

每次找的时候要写一个判断保证这个条件下所得到的两种魔方不为一个颜色

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
const int N = ; int a[N] , max_id[N] , sec_id[N]; //a[]保存离散化后的c struct Node{
int v , num;
}; vector<Node> vec[N];
#define ll long long
ll max_val[N] , sec_val[N] , sum[N]; struct Cube{
int c , s , num;
bool operator<(const Cube &m)const{
if(c == m.c) return s > m.s;
return c < m.c;
}
}cu[N]; int bin_search(int x , int k)
{
int l= , r = k-;
while(l<=r){
int m=(l+r)>>;
if(a[m] == x) return m;
else if(a[m]>x) r = m-;
else l = m+;
}
} int main()
{
// freopen("a.in" , "r" , stdin);
int n;
while(scanf("%d" , &n ) == )
{
for(int i= ; i<=n ; i++) vec[i].clear(); for(int i = ;i<n ; i++)
{
scanf("%d%d" , &cu[i].c , &cu[i].s);
cu[i].num = i+;
} sort(cu , cu+n);
int k = ;
a[k++] = cu[].c;
for(int i= ; i<n ; i++){
if(cu[i].c != cu[i-].c) a[k++] = cu[i].c;
} memset(sum , , sizeof(sum));
memset(max_val , , sizeof(max_val));
memset(sec_val , , sizeof(sec_val));
for(int i= ; i<n ; i++){
int index = bin_search(cu[i].c , k);
Node node;
node.num = cu[i].num , node.v = cu[i].s;
vec[index].push_back(node);
sum[index] = sum[index] + cu[i].s;
int len = vec[index].size();
if(max_val[len] < sum[index]){
sec_val[len] = max_val[len];
sec_id[len] = max_id[len]; max_val[len] = sum[index];
max_id[len] = index;
}
else if(sec_val[len] < sum[index]){
sec_val[len] = sum[index];
sec_id[len] = index;
}
}
// cout<<"test: "<<max_val[1]<<" index: "<<max_id[1]<<" "<<sec_id[1]<<endl;
int col1 , col2 , len1 , len2;
ll ans = ;
for(int len= ; len<=n ; len++){
if(max_val[len] && sec_val[len]){
if(max_id[len] != sec_id[len]){
if(ans < max_val[len]+sec_val[len]){
ans = max_val[len]+sec_val[len];
col1 = max_id[len];
col2 = sec_id[len];
len1 = len , len2 = len;
}
}
}
//长度不等的时候排除所有两种颜色一样的情况
if(max_val[len] && max_val[len+]){
if(max_id[len] != max_id[len+]){
if(ans < max_val[len]+max_val[len+]){
ans = max_val[len]+max_val[len+];
col1 = max_id[len];
col2 = max_id[len+];
len1 = len , len2 = len+;
}
}
}
if(sec_val[len] && max_val[len+]){
if(sec_id[len] != max_id[len+]){
if(ans < sec_val[len]+max_val[len+]){
ans = sec_val[len]+max_val[len+];
col1 = sec_id[len];
col2 = max_id[len+];
len1 = len , len2 = len+;
}
}
}
if(max_val[len] && sec_val[len+]){
if(max_id[len] != sec_id[len+]){
if(ans < max_val[len]+sec_val[len+]){
ans = max_val[len]+sec_val[len+];
col1 = max_id[len];
col2 = sec_id[len+];
len1 = len , len2 = len+;
}
}
}
} printf("%I64d\n%d\n" , ans , len1+len2);
printf("%d" , vec[col2][].num);
for(int i= ; i<len1 ; i++){
printf(" %d" , vec[col1][i].num);
if(i+<len2) printf(" %d" , vec[col2][i+].num);
}
puts("");
}
return ;
}

CodeForces 159E的更多相关文章

  1. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  2. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  3. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  4. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  5. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  6. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

  7. CodeForces - 261B Maxim and Restaurant

    http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...

  8. CodeForces - 696B Puzzles

    http://codeforces.com/problemset/problem/696/B 题目大意: 这是一颗有n个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不 ...

  9. CodeForces - 148D Bag of mice

    http://codeforces.com/problemset/problem/148/D 题目大意: 原来袋子里有w只白鼠和b只黑鼠 龙和王妃轮流从袋子里抓老鼠.谁先抓到白色老鼠谁就赢. 王妃每次 ...

随机推荐

  1. Navicat无法连接Oracle数据库问题处理一例

    需要通过Navicat连接Oracle数据库进行数据迁移,发现无法连接,报如下错误信息: 按照百度中的说明配置了正确的oci. 此时又报如下错误: 问题解决: 经测试发现与软件的版本有关系,本机的Or ...

  2. Android开发学习--RecycleView入门

    该控件用于在有限的窗口中展示大量数据集,其实这样功能的控件我们并不陌生,例如:ListView.GridView 通过设置它提供的不同LayoutManager,ItemDecoration , It ...

  3. 自动判断手机版和pc版

    <html><head><title>欢迎来到手机版</title><script>var ua = navigator.userAgent ...

  4. [BZOJ1009][HNOI2008]GT考试 DP+矩阵快速幂+KMP

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1009 我们令$dp(i,j)$表示已经填了$i$位,而且后缀与不幸运数字匹配了$j$位,那 ...

  5. 忘记dba用户密码,利用SQLPlus重置dba密码

    打开SQL Plus 输入用户名: sys as sysdba 输入口令:可直接回车 连接到: Oracle Database 11g Enterprise Edition Release 11.2. ...

  6. vue2.0生命周期函数

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. jQuery addClass removeClass toggleClass方法概述

    通过动态改变类名(class),可以让其修改元素呈现出不同的效果.在HTML结构中里,多个class以空格分隔,当一个节点(或称为一个标签)含有多个class时,DOM元素响应的className属性 ...

  8. 观锁和乐观锁——《POJOs in Action》

    1        事务隔离 事务隔离是数据库提供的功能. SQL Server通过SET TRANSACTION ISOLATION LEVEL语句设置事务隔离级别: SET TRANSACTION ...

  9. WebAPI中Area的使用

    很简单,创建area后,添加一下代码到AreaRegistration中即可 context.Routes.MapHttpRoute( name: "api_default", r ...

  10. MAC 添加共享,脚本执行

    Linux需要首先安装 yum install samba-client linxu添加windows 公共盘  mount -t cifs  user=guest,password=guest // ...