timus1965(不错的贪心)
题意是:给你一个1-n的排列,要你把这个排列分成两个序列,且这个两个序列都满足单调性。
题解:
1.首先假设找出的两个序列都是单调递增的(都是单调递减的同理)
那么很容易可以想到,将新加入的数放入到某个序列尾端,使得另一个序列尾端的数尽量小。
2.如果最后的两个序列为一个递增一个递减。
这种情况下,有一种眼光稍微长远一些的贪心策略。
假设当前要加入的数g[x],如果g[x]既可以放入单增序列中也可以放入单减序列中,则与g[x+1]比较。
if(g[x]>g[x+1]) 把g[x]放入单减序列中
else 把g[x]放入单增序列中
为什么这样贪心就行了?
可以做一个假设,当g[x]>g[x+1],我们却把g[x]放入单增序列中,则g[x]只能放入单减序列,最后得出的两个序列的尾部为:
xxxxg[x] (单增序列) 。。。。。。。。。方法一
xxxxxxg[x+1] (单减序列)
而当我们把g[x]放入单减序列时,此时g[x+1]可能放入单增序列中,一定可以放入单减序列中,
1.如果g[x+1] 放入单减序列中,得出两个序列尾部为:
xxxX (单增序列) 。。。。。。。。。方法二
xxxxxxg[x]g[x+1] (单减序列)
而X<g[x] ,所以下面这种方法得出的结果一定优于方法一。
2.如果g[x+1]能放入单增序列,放入其中得出的两个序列尾部为:
xxxxg[x+1] (单增序列) 。。。。。。。。。方法三
xxxxxxg[x] (单减序列)
因为g[x]>g[x+1],所以结果一定优于方法一。
把眼界放开,即使是贪心也能贪的漂亮!
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxN 100005
const int inf=~0U>>;
int s1[maxN];
int f[maxN][];
int N,len1,len2;
bool judge1()
{
f[][]=f[][]=-;
len1=len2=;
for(int i=;i<=N;i++)
{
if(s1[i]<f[len1][]&&s1[i]<f[len2][])
return false;
else if(s1[i]>f[len1][]&&s1[i]<f[len2][])
f[++len1][]=s1[i];
else if(s1[i]<f[len1][]&&s1[i]>f[len2][])
f[++len2][]=s1[i];
else
{
if(f[len2][]>f[len1][]) f[++len2][]=s1[i];
else f[++len1][]=s1[i];
}
}
if(len1==N) f[++len2][]=f[len1--][];
return true;
}
bool judge2()
{
f[][]=f[][]=inf;
len1=len2=;
for(int i=;i<=N;i++)
{
if(s1[i]>f[len1][]&&s1[i]>f[len2][])
return false;
else if(s1[i]>f[len1][]&&s1[i]<f[len2][])
f[++len2][]=s1[i];
else if(s1[i]<f[len1][]&&s1[i]>f[len2][])
f[++len1][]=s1[i];
else
{
if(f[len2][]<f[len1][]) f[++len2][]=s1[i];
else f[++len1][]=s1[i];
}
}
if(len1==N) f[++len2][]=f[len1--][];
return true;
}
bool judge3()
{
len1 = len2 = ;
f[len1][]=-;
f[len2][]=inf;
for(int i=;i<=N;i++)
{
if(s1[i]<f[len1][]&&s1[i]>f[len2][]) return false;
else if(s1[i]>f[len1][]&&s1[i]<f[len2][])
{
if(i==N) f[++len1][]=s1[i];
else if(s1[i+]>s1[i]) f[++len1][]=s1[i];
else f[++len2][]=s1[i];
}
else if(s1[i]>f[len1][])
f[++len1][]=s1[i];
else
f[++len2][]=s1[i];
}
return true;
}
int main()
{
scanf("%d",&N);
for(int i=,j=N;i<=N;i++,j--)
{
scanf("%d",&s1[i]);
}
if(judge1())
{
printf("%d %d\n",len1,len2);
for(int i=;i<=len1;i++) printf("%d%c",f[i][],i==len1?'\n':' ');
for(int i=;i<=len2;i++) printf("%d%c",f[i][],i==len2?'\n':' ');
return ;
}
if(judge2())
{
printf("%d %d\n",len1,len2);
for(int i=;i<=len1;i++) printf("%d%c",f[i][],i==len1?'\n':' ');
for(int i=;i<=len2;i++) printf("%d%c",f[i][],i==len2?'\n':' ');
return ;
}
if(judge3())
{
printf("%d %d\n",len1,len2);
for(int i=;i<=len1;i++) printf("%d%c",f[i][],i==len1?'\n':' ');
for(int i=;i<=len2;i++) printf("%d%c",f[i][],i==len2?'\n':' ');
return ;
}
printf("Fail\n");
//print1(dp1[len1]);
//printf("\n");
//print2(dp2[len2]);
return ;
}
另加一个,我自己想的丑陋的贪心。。。
//
// main.cpp
// timus1965
//
// Created by 陈加寿 on 16/3/16.
// Copyright © 2016年 chenhuan001. All rights reserved.
// #include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <map>
#include <set>
#include <math.h>
#include <algorithm>
using namespace std;
#define N 100100 int g[N],tg[N];
int ans1[N],ans2[N];
int cnt1,cnt2;
int n;
int b1,d1,b2,d2; int fuc()
{
cnt1 = cnt2 =;
//->
ans2[] = ;
ans1[ ++cnt1 ] = g[];
for(int i=;i<=n;i++)
{
if(g[i]<ans1[cnt1] && g[i]<ans2[cnt2])
{
return ;
}
//否则选尽量大的一边
if(g[i]>ans1[cnt1]) ans1[++cnt1]=g[i];
else ans2[++cnt2]=g[i];
}
return ;
} int fuc1()
{
cnt1 = cnt2 =;
//<-
ans2[] = n+;
ans1[ ++cnt1 ] = g[];
for(int i=;i<=n;i++)
{
if(g[i]>ans1[cnt1] && g[i]>ans2[cnt2])
{
return ;
}
//否则选尽量小的一边
if(g[i]<ans1[cnt1]) ans1[++cnt1]=g[i];
else ans2[++cnt2]=g[i];
}
return ;
} int test1(int b,int d)
{
if( tg[d]<b1 || tg[d]>d1 ) return ;// g[i]无法放入ans1中
//把(b,d)间的数全部放入ans2中去
//首先保证(b,d)之间是递减的
if(b+ == d)
{
ans1[++cnt1] = d;
b1 = tg[d];
return ;
}
for(int i=d-;i>b;i--)
{
if(tg[i]<tg[i+]) return ;//并不递减
}
if( tg[d-]>b2 && tg[b+]<d2 )
{
for(int i=d-;i>b;i--)
ans2[++cnt2] = i;
ans1[++cnt1] = d;
d2=tg[d-];
b1 = tg[d];
return ;
}
else return ;
} int test2(int b,int d)
{
if(tg[b]<b2 || tg[b]>d2) return ;
if(b+ == d)
{
ans2[++cnt2] = b;
b2 = tg[b];
return ;
}
for(int i=b+;i<d-;i++)
{
if(tg[i]>tg[i+]) return ;
}
if(tg[b+]>b1 && tg[d-]<d1)
{
for(int i=d-;i>b;i--)
ans1[++cnt1] = i;
ans2[++cnt2] = b;
d1 = tg[b+];
b2 = tg[b];
return ;
}
else return ;
} int solve()
{
int b=,d=n+;
b1=,d1=n+;
b2=,d2=n+;
//并不需要set
for(int i=;i<=n;i++)
{
if( g[i]<b || g[i]>d) continue; //已经处理过的,不再处理
if(g[i]-b < d-g[i])
{
//靠左,g[i]放入ans1中
if( test1(b,g[i])== )
{
//如果
b = g[i];
}
else if(test2(g[i],d)==)
{
d = g[i];
}
else return ;//两个测试都不过 直接返回不行.
}
else
{
//靠右
if(test2(g[i],d)==)
{
d=g[i];
}
else if(test1(b, g[i])==)
{
b=g[i];
}
else return ;
}
}
return ;
} int cmp(int x,int y)
{
return x>y;
} int main() {
cin>>n; for(int i=;i<=n;i++)
{
scanf("%d",g+i);
tg[ g[i] ] = i;
}
g[]=; g[n+]=n+;
tg[]=; tg[n+]=n+;
cnt1 = cnt2 = ;
int flag=;
//step one tha same direction
if( fuc() || fuc1() )
{
flag=;
}
if(flag == )
{
// step two the different direction
cnt1 = cnt2 =;
flag = solve();
//最后再sort一下
sort(ans1+,ans1++cnt1);
sort(ans2+,ans2++cnt2,cmp);
}
if(flag == )
{
printf("Fail\n");
}
else
{
//输出答案
if(cnt1==n)
{
ans2[++cnt2] = ans1[cnt1--];
}
if(cnt2==n)
{
ans1[++cnt1] = ans2[cnt2--];
}
cout<<cnt1<<" "<<cnt2<<endl;
for(int i=;i<=cnt1;i++) printf("%d ",ans1[i]);
printf("\n");
for(int i=;i<=cnt2;i++) printf("%d ",ans2[i]);
printf("\n");
}
return ;
}
timus1965(不错的贪心)的更多相关文章
- hdu4450 不错的贪心
题意: 卡片游戏 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total S ...
- BZOJ4977: [[Lydsy1708月赛]跳伞求生(不错的贪心)
4977: [[Lydsy1708月赛]跳伞求生 Time Limit: 5 Sec Memory Limit: 256 MBSubmit: 446 Solved: 142[Submit][Sta ...
- BZOJ3016: [Usaco2012 Nov]Clumsy Cows
3016: [Usaco2012 Nov]Clumsy Cows Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 71 Solved: 52[Submi ...
- The 16th Zhejiang provincial collegiate programming contest
今天我挺有状态的,看过的题基本都给了正解(可能是昨晚cf div3打得跟屎一样,人品守恒,不好意思发题解了),自己也给队伍签了很多水题(不敢让队友写,怕出锅). 最后6题滚了,有点可惜.还差B和K没做 ...
- jzyz 题库 题目选做
题库中也有很多我想不出来的模拟赛的题目.做还是必要的.做自己的题目 时间很紧 想想自己的文化课 我又没有那么强 我必须得刷. LINK:水题一道 发现是一道计数题 计数题拿高分的才是王者,但是 计数题 ...
- POJ3040给奶牛发工资
题意: 有n种硬币,每种硬币有mi个,然后让你给奶牛发工资,每周发至少c元(就是不找零钱的意思)然后问你能发几周?(硬币之间都是倍数关系) 思路: 这个题目做了两天,丢脸,看完 ...
- [考试总结]noip模拟43
这个题目出的还是很偷懒.... 第一题...第二题...第三题...四.... 好吧... 这几次考得都有些问题,似乎可能是有些疲惫,脑袋也是转不太动,考完总觉得自己是能力的问题,但是改一分钟之后会发 ...
- SPOJ:Decreasing Number of Visible Box(不错的,背包?贪心?)
Shadowman loves to collect box but his roommates woogieman and itman don't like box and so shadowman ...
- SPOJ:Strange Waca(不错的搜索&贪心&剪枝)
Waca loves maths,.. a lot. He always think that 1 is an unique number. After playing in hours, Waca ...
随机推荐
- [Spring boot] Integrating with h2 database
In pom.xml add dependency: <dependencies> <dependency> <groupId>org.springframewor ...
- maven运行junit用例并生成报告maven-surefire-plugin,maven-antrun-extended-plugin
转载:http://blog.csdn.net/hdyrz/article/details/78398964 测试类如下: package com.mmnn.test.testcase; import ...
- [转载]linux 更新yum源 改成阿里云源
原文链接:https://www.cnblogs.com/bincoding/p/7892762.html 1.备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc ...
- Loadrunner Analysis之Web Page Diagnostics
Loadrunner Analysis之Web Page Diagnostics 分类: LoadRunner 性能测试 2012-12-31 18:47 1932人阅读 评论(2) 收藏 举报 di ...
- C语言文件操作函数大全(超详细)
C语言文件操作函数大全(超详细) 作者: 字体:[增加 减小] 类型:转载 本篇文章是对C语言中的文件操作函数进行了详细的总结分析,需要的朋友参考下 fopen(打开文件)相关函数 open,fc ...
- Redis之SkipList数据结构
0.前言 Redis中有序集合zset需要使用skiplist作为存储数据结构, 关于skiplist数据结构描述可以查询wiki, 本文主要介绍Redis实现的skiplist的细节. 1.数据结构 ...
- 查看zookeeper是否启动
查看进程: 方法: ps -aux | grep 'zookeeper' 系统有返回,说明zookeeper启动. 你可以搜索ps -aux.
- 文件上传下载:commons-fileupload + Servlet 2.5
数据库:MySQL 开发技术:JSP + Servlet 2.5 第三方的上传组件: commons-fileupload connons-io 上传页面1.form表单需要增加:enctype=&q ...
- 在python中Flask配置服务
from flask import Flask, request from data_util import UtilsLTPTranslate import json model = UtilsLT ...
- Trees in a Wood. UVA 10214 欧拉函数或者容斥定理 给定a,b求 |x|<=a, |y|<=b这个范围内的所有整点不包括原点都种一棵树。求出你站在原点向四周看到的树的数量/总的树的数量的值。
/** 题目:Trees in a Wood. UVA 10214 链接:https://vjudge.net/problem/UVA-10214 题意:给定a,b求 |x|<=a, |y|&l ...