Luogu 1311(dp/模拟)(NOIP 2011)

传送门

NOIP 2011 D1T2

题解:

1.dp,有O(n),下面是三月份测试写的O(n*k)的:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=200004;
int n,k,p;//客栈数,色调数,max 
int c,m;//色调,花费
int num[maxn][51],s[maxn][51];//i点之前j色调客栈数,i点之前满足条件的j色调客栈数 
int res=0;
int main() {
	memset(num,0,sizeof(num));
	memset(s,0,sizeof(s));
	scanf("%d%d%d",&n,&k,&p);
	for (int i=1;i<=n;i++) {
		scanf("%d%d",&c,&m);
		if (m<=p) {
			for (int j=0;j<k;j++)
				num[i][j]=num[i-1][j],s[i][j]=num[i][j];
			res+=s[i][c]++;
			num[i][c]++;
		}
		else {
			for (int j=0;j<k;j++)
				num[i][j]=num[i-1][j],s[i][j]=s[i-1][j];
			res+=s[i][c];
			num[i][c]++;
		}
	}
	printf("%d\n",res);
	return 0;
} 
2.模拟:(转自zbtrs,大概就是从前往后扫,只考虑前面的和当前点组成的对,当前加不了的贡献用一个临时数组存起来,后面满足条件时在加到答案上)

在右边,若是其左边有一个符合要求的咖啡店,那么再往左边看,如果有一个颜色相同的旅店,那么就算是一种住宿方法了,那么如果以这个右边的旅店作为对应点,将所有在左边而且颜色与之相同的旅店数相加,就能得出很多种住宿方法了。那么用这个办法,用所有的对应点对应过去,就能最快的时间内找出所用的酒店了。a数组是记录同一种颜色中的酒店所出现的最后一次的位置;b数组记录同一种颜色的酒店的出现次数,而c数组则是临时记录当前同样颜色的酒店出现的次数,也就是为找对应点而进行的临时记录。 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int last[52],sum[52],temp[52];
int n,m,p,col,val,cur,ans=0;
int main() {
	scanf("%d%d%d",&n,&m,&p);
	for (int i=1;i<=n;++i) {
		scanf("%d%d",&col,&val);
		if (val<=p) cur=i;
		if (cur>=last[col]) sum[col]=temp[col];
		last[col]=i,ans+=sum[col],++temp[col];
	}
	printf("%d\n",ans);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值