2018 AICCSA Programming Contest——H. Win Strategy

题目描述

H. Win Strategy

time limit per test

2.0 s

memory limit per test

256 MB

input

standard input

output

standard output

You are at a programming contest where there will be nn problems. For each problem you know at what time it will be available for you to read (and solve). Also you know how much time you need to solve it.

To solve a problem, you need to spend the needed time continuously without switching between different problems.

Find the maximum number of problems you can solve in the given contest time.


输入输出

Input

The first line of input contains a single integer TT (1≤T≤2501≤T≤250), the number of test cases.

The first line of each test case contains two space-separated integers nn and LL (1≤n,L≤10001≤n,L≤1000), the number of problems and the length of the contest, respectively.

Each of the following nn lines contains two space-separated integers aiai and bibi (1≤ai,bi≤L1≤ai,bi≤L), which means the ithith problem will be available at minute aiai and you need bibi minutes to solve it.

Problems will be given in a non-decreasing order of aiai.

Output

For each test case, output a single line with the maximum number of problems you can solve during the contest.


样例

input

1
4 10
1 3
1 2
1 6
2 2

output

3


分析

很显然的区间动规。

每个区间可以取某个位置及其之后的位置,求不重复的区间的最大个数。

f【i,j】表示考虑到第i个问题,在位置j使用区间i,能获得的区间的最大个数。

//但是为什么从后往前算就不对了呢?


代码

#include<bits/stdc++.h>
using namespace std;
//为什么从后往前就不对呢??? 
int n,m;
int f[1005][2005];
int p[2005],Len[2005];
void Init()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d%d",&p[i],&Len[i]);
}
void Solve()
{
	memset(f,0,sizeof(f));
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)f[i][j]=f[i-1][j];//i not used
		for(int j=p[i]+Len[i]-1;j<=m;j++)//i used
		{
			f[i][j]=max(f[i][j],f[i-1][j-Len[i]]+1); 
		}
		for(int j=1;j<=m;j++)f[i][j]=max(f[i][j],f[i][j-1]);
	}
	printf("%d\n",f[n][m]);
}
void Check()
{
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			printf("%d  %d  %d\n",i,j,f[i][j]);
		}
		printf("\n");
	}
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		Init();
		Solve();
		//Check(); 
	}
	return 0;
}
/*
3 10
1 10
2 5
2 3

1
2 10
1 2
10 1
*/

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值