ACM集训day3
来源:互联网 发布:知乎关注最多的人 编辑:程序博客网 时间:2024/05/01 20:33
7.13
要点:贪心算法
note:分成子问题,分别求最优解
找规律->得猜想->证猜想->写代码
例题:hdu2037、hdu2021、nyoj891
常用技巧: 0.sort函数的使用
1.sort自定义排序规则sort(,,cmp)
2.结构体排序
思考题:
nyoj1170
描述
小明和小红在打赌说自己数学学的好,于是小花就给他们出题了,考考他们谁NB,题目是这样的给你N个数
在这n个数之间添加N-1个*或+,使结果最大,但不可以打乱原顺序,请得出这个结果
如
1 3 5
结果是(1+3)*5=20;最大
可以添加若干个括号,但一定要保证配对,但是每两个数之间只可能有一个*或+
数列最前和最后不应有+或乘
小明想赢小红但是他比较笨,请你帮帮他
输入
多组测试数据以EOF结束,每组有一个n(n<10000),然后有n个正整数a[i](1<=a[i]<=20)
输出
输出最大的结果由于结果比较大,结果对10086取余
练习
A题 发工资咯:)
note:好久没做过这种输入0就结束程序的了,还以为每个样例以0结束my god…MARK一下
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int a[10005];bool cmp(int a,int b) //sort大到小排{ return a>b;}int main(){ int n; int c[6]={100,50,10,5,2,1}; while(scanf("%d",&n)!=EOF&&n) //0结束 { memset(a,0,sizeof(a)); int i,j; int count=0; for(i=0;i<n;i++) { scanf("%d",&a[i]); if(!a[i]) break; } sort(a,a+n,cmp); //可以不要排序,没多大意义 for(i=0;i<n;i++) for(j=0;j<6;j++) { if(c[j]>a[i]) continue; else if(c[j]==a[i]) { count++; break; } else { int t; t=a[i]/c[j]; count+=t; a[i]=a[i]%c[j]; } } printf("%d\n",count); } return 0;}
============================我是分割线===============================
C题 Crossing River
**
note:多找找规律
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int main(){ int i,n,t; scanf("%d",&t); while(t--) { int time=0,a[1000]; scanf("%d",&n); for(i=0;i<n;i++) { scanf("%d",&a[i]); } sort(a,a+n); //time=a[0]+a[1]+a[n-1]; while(n>=4) { int t1,t2; t1=a[0]+a[1]*2+a[n-1]; //两个最慢的走 t2=a[n-1]+a[n-2]+a[0]*2; //最快的来回带慢的飞~ time+=min(t1,t2); //比较取时间少的方案 n-=2; } if(n==3) time+=a[0]+a[1]+a[2]; else if(n==2) time+=a[1]; else if(n==1) time+=a[0]; printf("%d\n",time); } return 0;}
D题 今年暑假不AC
note:结构体排序,真的很好用!按结束时间升序
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;struct temp{ int a,b;};typedef struct temp T;bool cmp(T m,T n){ return m.b<n.b;}int main(){ int n,i,j; while(scanf("%d",&n)!=EOF&&n) { T f[1000]; int count=1; for(i=0;i<n;i++) { scanf("%d %d",&f[i].a,&f[i].b); } sort(f,f+n,cmp); for(i=1,j=0;i<n;i++) if(f[i].a>=f[j].b) { j=i; count++; } printf("%d\n",count); } return 0;}
============================我是分割线===============================
E题 Hero
**
note:这题跟基友讨论了很久,终于理解透彻了!
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;struct temp{ double dp,hp; /*这里用double,是为了下面(*)式子中的除法能比较出高下,否则31/3和20/2是一样的*/};typedef struct temp T;bool cmp(T m,T n){ /*double d1,d2; //如果上面用int,这里就不能去掉,下面改成return d1>d2; d1=1.0*m.dp/m.hp; d2=1.0*n.dp/n.hp;*/ //(*) return (m.dp/m.hp)>(n.dp/n.hp); //(**) /*原来WA是因为上面(*)虽然注释掉,但是作用没发挥出来,结构体那里又用了int,导致排序出问题 dps/hp来计算敌人的威胁程度是因为我联想到初高中的时候,我参加铅球比赛,我几乎是成绩是排3,然而我的体重几乎是全场最轻,就是说用 距离/体重 来算成绩的话,我肯定就是第一了...*/}int main(){ int n,i; while(scanf("%d",&n)!=EOF) { T f[1000]; int attack=0; int loss=0; for(i=0;i<n;i++) { scanf("%lf %lf",&f[i].hp,&f[i].dp); attack+=f[i].dp; } sort(f,f+n,cmp); for(i=0;i<n;i++) { loss+=attack*f[i].hp; attack-=f[i].dp; } printf("%d\n",loss); } return 0;}
============================我是分割线===============================
F题 Subsequence
**
note:用到记忆化的思想,节省时间
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int a[100005];int sum[100005];int main(){ int n,s,i,j,t; scanf("%d",&t); while(t--) { scanf("%d %d",&n,&s); memset(a,0,sizeof(a)); memset(sum,0,sizeof(sum)); int ans=n+1; for(i=0;i<n;i++) scanf("%d",&a[i]); for(i=1;i<=n;i++) { sum[i]=sum[i-1]+a[i-1]; //名副其实的前i项,就是sum[0]==0; } int j=1; int tag=1; if(a[0]>=s) ans=1; else if(sum[n]<s); //打分号,不作处理~一开始就看总和是否大于s //ans=n+1; else{ for(i=1;i<=n;i++) /*虽然这里是二层循环,但是时间复杂度只是第一层的线性关系,并不是 指数关系,因为第二层循环的j实际上是跟第一层的i是并驱的,sum[j]-sum[i-1]一旦大于s,j就停下来等i*/ { for(;sum[j]-sum[i-1]<s;) { if(j==n) tag=0; j++; } if(j<=n&&sum[j]-sum[i-1]>=s) ans=min(ans,j-i+1); //取范围最小值 if(!tag) break; } } if(ans<=n) printf("%d\n",ans); else printf("0\n"); } return 0;}
对F题的循环用表格举例子描述一下:如输入n=10,s=15 5 6 7 10
*由此可见时间复杂度只是n的线性关系O(n)
贪心算法感觉学得不是很好,我是不是不怎么贪心啊(逃
过题排前几的都是贪心鬼!(捂脸
- ACM集训day3
- CCNU ACM 2016夏季集训·day3比赛
- 湖南集训Day3
- 20160124集训Day3-数学
- zzuacm集训day3
- 省队集训DAY3
- 沈阳集训day3
- 暑期集训 DAY3
- 集训题解-Day3
- 郑州集训DAY3笔记
- 北京集训DAY3
- xor 2016 国庆集训day3
- 5月集训Day3考试
- 省队集训Round2 DAY3
- 国庆郑州集训day3:数据结构
- 福建省队集训被虐记——DAY3
- 陕西省集训day3(搜索上)
- 2016国庆集训day3-minimum.cpp
- 关于SIGTERM信号
- Python 爬虫 PhantomJs 获取JS动态数据
- 【结论】树状数组
- Leetcode 第 374 题(Guess Number Higher or Lower)
- leetcode---Remove Duplicates from Sorted List II---链表
- ACM集训day3
- ROUTE命令
- c# 之输出参数(out)
- 进一步简化你的 ViewHolder
- Android 创建简单的Observer实例
- (NSString)copy strong
- 347. Top K Frequent Elements
- 2016暑假集训总结——Part1
- 韦东山项目视频之摄像头驱动1 V4L2框架分析