D. Boxes Packing(思维-反向思考)

https://codeforces.com/problemset/problem/1066/D


 

题目描述

Maksim has nn objects and mm boxes, each box has size exactly kk . Objects are numbered from 11 to nn in order from left to right, the size of the ii -th object is a_iai​ .

Maksim wants to pack his objects into the boxes and he will pack objects by the following algorithm: he takes one of the empty boxes he has, goes from left to right through the objects, and if the ii -th object fits in the current box (the remaining size of the box is greater than or equal to a_iai​ ), he puts it in the box, and the remaining size of the box decreases by a_iai​ . Otherwise he takes the new empty box and continues the process above. If he has no empty boxes and there is at least one object not in some box then Maksim cannot pack the chosen set of objects.

Maksim wants to know the maximum number of objects he can pack by the algorithm above. To reach this target, he will throw out the leftmost object from the set until the remaining set of objects can be packed in boxes he has. Your task is to say the maximum number of objects Maksim can pack in boxes he has.

Each time when Maksim tries to pack the objects into the boxes, he will make empty all the boxes he has before do it (and the relative order of the remaining set of objects will not change).

输入格式

The first line of the input contains three integers nn , mm , kk ( 1 \le n, m \le 2 \cdot 10^51≤n,m≤2⋅105 , 1 \le k \le 10^91≤k≤109 ) — the number of objects, the number of boxes and the size of each box.

The second line of the input contains nn integers a_1, a_2, \dots, a_na1​,a2​,…,an​ ( 1 \le a_i \le k1≤ai​≤k ), where a_iai​ is the size of the ii -th object.

输出格式

Print the maximum number of objects Maksim can pack using the algorithm described in the problem statement.

题意翻译

题意描述:

你有nn个物品,每个物品大小为a_iai​,mm个盒子,每个盒子的容积为kk。MaksimMaksim先生想把物品装入盒子中。对于每个物品,如果能被放入当前的盒子中,则放入当前盒子,否则换一个新的盒子放入。为了放入尽可能多数量的物品,MaksimMaksim先生会从左开始扔掉一部分物品。当剩下的物品全部能被放入盒子时,这种方案才算合法。现在,MaksimMaksim先生想知道,他最多能放入盒子多少物品(方案必须合法)。

输入输出格式:

输入格式:

第一行,三个整数nn,mm,kk,(1≤n,m≤2 \times 10^5(1≤n,m≤2×105,1≤k≤10^9)1≤k≤109)含义参见上文

第二行,nn 个数,第ii表示a_iai​

输出格式:

一行,一个数,表示MaksimMaksim先生能放入盒子里的最多的物品数量

输入输出样例

输入 #1复制

5 2 6
5 2 1 4 2

输出 #1复制

4

输入 #2复制

5 1 4
4 2 3 4 1

输出 #2复制

1

输入 #3复制

5 3 3
1 2 3 1 1

输出 #3复制

5

说明/提示

In the first example Maksim can pack only 44 objects. Firstly, he tries to pack all the 55 objects. Distribution of objects will be [5], [2, 1][5],[2,1] . Maxim cannot pack the next object in the second box and he has no more empty boxes at all. Next he will throw out the first object and the objects distribution will be [2, 1], [4, 2][2,1],[4,2] . So the answer is 44 .

In the second example it is obvious that Maksim cannot pack all the objects starting from first, second, third and fourth (in all these cases the distribution of objects is [4][4] ), but he can pack the last object ( [1][1] ).

In the third example Maksim can pack all the objects he has. The distribution will be [1, 2], [3], [1, 1][1,2],[3],[1,1] .


注意原文标黑体的一句话:he will throw out the leftmost object from the set until the remaining set of objects can be packed in boxes he has.就是说要剩下的全都能装起来的时候这个方案才是合法的。

注意数据是a[i]<=k,所以不会有一个箱子装不下的物品。

反向思考,因为剩下的全部装起来,所以能最后一个能装的的肯定在最右边。

所以从后往前装,如果当前能装进去就装进去。如果当前装不进去就要新拿一个箱子,当箱子没了的时候就是最多能满足的状态了。

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+100;
typedef long long LL;
LL a[maxn],b[maxn]; 
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL n,m,k;cin>>n>>m>>k;
  for(LL i=1;i<=n;i++){
  	cin>>a[i];
  }
  for(LL i=1;i<=n;i++) b[i]=a[n-i+1];
  LL used=0;LL res=m;
  for(LL i=1;i<=n;i++){
  	if(b[i]+used>k){
  		res--;used=b[i];
		if(res==0){
			cout<<i-1<<endl;
			return 0;
		}  	
	}
	else used+=b[i];
  }	
  cout<<n<<endl;
return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值