18.04.14 noip2011D2 总结+题解


应老李的要求来写一写每周の博客...

真的好麻烦啊

今天考了2011年noip D2的题..

喔好难啊...

第一题只有80分 第二题半暴力只拿了一半的分 第三题直接不会做...

还是做题做少了呀

现在总结一波

第一题

求(ax+by)^k 的x^ny^m项的系数 (m+n=k)

看题目就是一道二项式定理 但是由于我忘记系数是怎么求的了(逃 

 所以我就想的递推 班上还有小伙伴打了个杨辉三角形板子然后加快速幂

至于80分的原因是没有好好读题 (日常不读题1/1  忽略掉了k=0的情况...好可惜啊

代码 (注释掉的是杨辉三角形的板子

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define mod 10007

using namespace std;
typedef long long ll;

int a,b,n,m,k;
ll s[1001][1001];

int main(){
	freopen("factor.in","r",stdin);
	freopen("factor.out","w",stdout);
	scanf("%d%d%d%d%d",&a,&b,&k,&n,&m);
	/*if(a==1&&b==1){
		s[1][1]=1;
	    s[1][2]=2;
	    for(int i=2;i<=k;i++)
	      s[i][1]=1;
	    for(int i=2;i<=k;i++)
	      s[i][i+1]=1;
	    for(int i=2;i<=k;i++)
	      for(int j=2;j<=i;j++)
	        s[i][j]=(s[i-1][j-1]%mod+s[i-1][j]%mod)%mod;
	    printf("%I64d",s[k][m+1]);
	}
	else {*/
	if(k==0){
	  printf("1");
	  return 0;	
	}
	s[1][1]=a%mod;
	s[1][2]=b%mod;
	for(int i=2;i<=k;i++)
	  s[i][1]=s[i-1][1]*a%mod;
	for(int i=2;i<=k;i++)
	  s[i][i+1]=s[i-1][i]*b%mod;
	for(int i=2;i<=k;i++)
	  for(int j=2;j<=i;j++)
		s[i][j]=(s[i-1][j]*a%mod+s[i-1][j-1]*b%mod)%mod;//递推
	printf("%I64d",s[k][m+1]);
	//}
	return 0;
}

第二题

有n个物品 给一个重量wi 以及价值vi 检验这批物品。
1、给定m 个区间[Li,Ri];
2、选出一个参数W;

3、对于一个区间[Li,Ri],计算检验值

  j 是物品编号

这批物品的检验结果Y 为各个区间的检验值之和。即:


给定一个标准值S 通过调整参数W 的值 让检验结果尽可能的靠近标准值S

即 使得S-Y 的绝对值最小 求出这个最小值。

其实就是一道二分W的题

但是我在检验二分值的时候复杂度太高了 当时想了一个伪线段树 后来才知道可以用前缀和 

他们真的好聪明啊

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;
typedef long long ll;

const ll N=200000+5;
ll s,ans;
ll n,m,v[N],w[N],f[N],num[N];

struct section{
	ll lf,rg;
}q[N];

ll work(ll x){
	memset(num,0,sizeof(num));
	memset(f,0,sizeof(f));
	for(ll i=1;i<=n;i++){
		if(w[i]>=x){
			num[i]=1;
			f[i]=v[i];
		}
		f[i]+=f[i-1];
		num[i]+=num[i-1];
	}
	ll ans=0;
	for(ll i=1;i<=m;i++){ //前缀和
		int ll=q[i].lf;
		int rr=q[i].rg;
		ans=ans+(num[rr]-num[ll-1])*(f[rr]-f[ll-1]);
	}
	return ans;
}

int main(){
	freopen("qc.in","r",stdin);
	freopen("qc.out","w",stdout);
	scanf("%I64d%I64d%I64d",&n,&m,&s);
	ll minw=1e9;
	ll maxw=-minw;	
	for(ll i=1;i<=n;i++){
	  scanf("%I64d%I64d",&w[i],&v[i]);
	  if(w[i]>maxw) maxw=w[i];
	  if(w[i]<minw) minw=w[i];		
	}
	for(ll i=1;i<=m;i++)
	  scanf("%I64d%I64d",&q[i].lf,&q[i].rg);
	ll l=minw,r=maxw+1;
	ll ans=1e18;
	while(l<=r){   //二分
		ll mid=(l+r)>>1;
		ll cmp=work(mid);
		ll delta=abs(s-cmp);
		if(delta<ans) ans=delta;
		if(cmp<s) r=mid-1;
		else if(cmp>s) l=mid+1;
		else break;
	}
	printf("%I64d",ans);
	return 0;
}

第三题

啊 好难

题目大意:

...

.....

算了不大意了 概括没学好 概括不来这题 直接上题

【问题描述】
风景迷人的小城 Y 市,拥有n 个美丽的景点。由于慕名而来的游客越来越多,Y 市特
意安排了一辆观光公交车,为游客提供更便捷的交通服务。观光公交车在第0 分钟出现在1
号景点,随后依次前往2、3、4……n 号景点。从第i 号景点开到第i+1 号景点需要Di 分钟。
任意时刻,公交车只能往前开,或在景点处等待。
设共有 m 个游客,每位游客需要乘车1 次从一个景点到达另一个景点,第i 位游客在
Ti 分钟来到景点Ai,希望乘车前往景点Bi(Ai<Bi)。为了使所有乘客都能顺利到达目的地,
公交车在每站都必须等待需要从该景点出发的所有乘客都上车后才能出发开往下一景点。
假设乘客上下车不需要时间。
一个乘客的旅行时间,等于他到达目的地的时刻减去他来到出发地的时刻。因为只有一
辆观光车,有时候还要停下来等其他乘客,乘客们纷纷抱怨旅行时间太长了。于是聪明的司
机ZZ 给公交车安装了k 个氮气加速器,每使用一个加速器,可以使其中一个Di 减1。对于
同一个Di 可以重复使用加速器,但是必须保证使用后Di 大于等于0。

那么 ZZ 该如何安排使用加速器,才能使所有乘客的旅行时间总和最小?

输入

第 1 行是3 个整数n, m, k,每两个整数之间用一个空格隔开。分别表示景点数、乘客数
和氮气加速器个数。
第 2 行是n-1 个整数,每两个整数之间用一个空格隔开,第i 个数表示从第i 个景点开
往第i+1 个景点所需要的时间,即Di。
第 3 行至m+2 行每行3 个整数Ti, Ai, Bi,每两个整数之间用一个空格隔开。第i+2 行表

示第i 位乘客来到出发景点的时刻,出发的景点编号和到达的景点编号。

输出最小的旅行时间

这道题 我开始想的贪心 乱贪一气还觉得自己贪的天衣无缝...

后来才发现自己还是太年轻了 (永远不要相信小样例..

#include<cstdio>
#include<cstring>
#include<iostream>

using namespace std;

const int maxint=1000000000; 

int n,m,k;d[10001],t[10001],a[10001],b[10001],latest[10001],
int arrive[10001],sum[10001],next[10001],ans=0,qqq,dd,maxl;
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
int main(){
    freopen("bus.in","r",stdin);
    freopen("bus.out","w",stdout);
    
    memset(latest,0,sizeof(latest));
    memset(sum,0,sizeof(sum));
    
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n-1;i++)
       scanf("%d",&d[i]);
    for(int i=1;i<=m;i++){
       scanf("%d%d%d",&t[i],&a[i],&b[i]);
       if(t[i]>latest[a[i]])
          latest[a[i]]=t[i];
       sum[b[i]]++;
    }
    for(int i=1;i<=n;i++) 
      sum[i]+=sum[i-1];
    
    while(1){
         maxl=1;
         //计算arrive[i]  表示bus到达第i个景点的时间。
         arrive[1]=0;
         for(int i=2;i<=n;i++)
            arrive[i]=max(arrive[i-1],latest[i-1])+d[i-1];
         //计算next[i]表示在第i个景点后离第i个景点最近的满足latest[i]>=arrive[i](即bus到的时间比最后到的乘客时间早)的景点。
         //即第i个景点到next[i]-1个景点均是bus到的时间比最后到的乘客时间晚
         next[n]=n;
         for(int i=n-1;i;i--){
             next[i]=next[i+1];
             if(arrive[i+1]<=latest[i+1])
                next[i]=i+1;
             }
         //贪心选择最优的一条边操作,一次操作可以直接使d[i]变为0
         while(!d[maxl]&&maxl<=n-1)
               maxl++;
         if(maxl==n||k==0)
            break;
         for(int i=maxl+1;i<=n-1;i++)
            if(d[i]&&sum[next[maxl]]-sum[maxl]<sum[next[i]]-sum[i])//选择加速要让最多的人受益,只有到达了目的地的乘客才是真正受益。
               maxl=i;                                             //经过的乘客不一定受益 因为虽然现在加速了 但后面可能因为等晚到的乘客而没有真正受益
         if(sum[next[maxl]]-sum[maxl]==0)
            break;
         dd=maxint;
         for(int i=maxl+1;i<=next[maxl]-1;i++)
            dd=min(dd,arrive[i]-latest[i]);    
         dd=min(dd,k);
         dd=min(dd,d[maxl]);
         k-=dd;
         d[maxl]-=dd;
    }
    
    for(int i=1;i<=m;i++)
        ans+=arrive[b[i]]-t[i];
    printf("%d",ans);
    
    fclose(stdin);
    fclose(stdout);
    return 0;
}

终于写完了..

下周可能还要被老李喊来写这个吧...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
大学生在线租房平台管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、报修评价管理、字典管理、房东管理、房屋管理、房屋收藏管理、房屋留言管理、房屋租赁管理、租房论坛管理、公告信息管理、留言板管理、用户管理、管理员管理。用户的功能等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 大学生在线租房平台管理系统可以提高大学生在线租房平台信息管理问题的解决效率,优化大学生在线租房平台信息处理流程,保证大学生在线租房平台信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理大学生在线租房平台信息,包括房屋管理,培训管理,报修管理,薪资管理等,可以管理公告。 房屋管理界面,管理员在房屋管理界面中可以对界面中显示,可以对房屋信息的房屋状态进行查看,可以添加新的房屋信息等。报修管理界面,管理员在报修管理界面中查看报修种类信息,报修描述信息,新增报修信息等。公告管理界面,管理员在公告管理界面中新增公告,可以删除公告。公告类型管理界面,管理员在公告类型管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值