3/01个人训练

3/01个人训练

D. PriceFixed

这是昨天打的VP的d题,今天补一下。

题目大意:

有n个东西,每一件都是两元。第i件物品需要买ai个,购买物品总数达到bi后,所有的i物品都变成一元。问买完所有物品最少花多少钱。

思路和代码:

我的初始想法是:先买bi最大的物品,然后取比对最少的ai。用两个数组,一个按照bi降序,一个按照ai升序取比对。但是这样操作起来不太容易。

正解是排序后双指针。

struct p {
	ll num , need ;
};

bool cmp(p u , p v){
	if(u.need == v.need) return u.num < v.num ;
	return u.need < v.need ;
}

void solve(){
	cin >> n ;
	vct<p> a(n , {0 , 0}) ;
	
	rep(i , 0 , n - 1) cin >> a[i].num >> a[i].need ;
	
	sort(a.begin() , a.end() , cmp) ;
	ll ans = 0 , m = 0 ;
	ll l = 0 , r = n - 1 ;
	while(l <= r){
		while(l <= r && m < a[l].need){
			ll x = min(a[r].num , a[l].need - m) ;
			ans += x * 2 ;
			m += x ;
			a[r].num -= x ;
			if(!a[r].num) r -- ;
		}
		if(r < l) break ;
		ans += a[l].num ;
		m += a[l].num ;
		l ++ ;
	}
	cout << ans ;
	
}
小结:

老会想到优先队列去解题,搞得很复杂,应该可以去做PQ的相关练习,明确PQ一般可以用来干什么。

树状数组学习:

1.楼兰图腾

单点修改单点查询的例子

2.一个简单的整数问题
题目大意:

n个数字,有两种操作,第一种操作是将[l,r]区间的所有数字都加上c,第二种操作是查询下标为x的数字。

思路和代码:

区间修改单点查询。利用差分数组实现方便的区间修改,而差分数组的前缀和就是该位置的单点数值。

ll n , m ;
ll tr[N] ;

ll lowbit(ll idx){
	return idx & -idx ;
}

ll sum(ll idx){
	ll res = 0 ;
	for(ll i = idx ; i ; i -= lowbit(i)) res += tr[i] ;
	return res ;
}

void add(ll idx , ll x){
	for(ll i = idx ; i <= n ; i += lowbit(i)) tr[i] += x ;
}

ll query(ll idx){
	return sum(idx) ;
}

void solve(){
	cin >> n >> m ;
	
	vct<ll> a(n + 1 , 0) ;
	vct<ll> b(n + 1 , 0) ;
	
	rep(i , 1 , n) cin >> a[i] ;
	
	b[1] = a[1] ;
	
	rep(i , 2 , n) b[i] = a[i] - a[i - 1] ;//差分数组 
	
	rep(i , 1 , n) add(i , b[i]) ;
	
	while(m -- ){//cout << m << "\n" ;
		char op ; cin >> op ;
		if(op == 'Q'){
			ll idx ; cin >> idx ;
			cout << query(idx) << "\n" ;
		}else{
			ll l , r , c ;
			cin >> l >> r >> c ;
			add(l , c) ;
			add(r + 1 , -1 * c) ;
		}
	}
}//code_by_tyrii 
posted @   tyrii  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示