Kim is a college student who love computer games, but unfortunately his school just published a rule that Games should disappear in the campus , that means nobody can play computer games in school, including the students dormitory. However, the student don’t take it seriously, that’s why the manager of the school gets so angry that he decided to go to the dormitory to punish the students. You should know the manager will punish those students who is playing games at the moment he enter the room, and leave immediately if nobody is playing game in this room.
Kim is a talented game player , in fact, he is the Carry of a famous Gaming club, so he needs time to practice he’s skills . And luckily , Kim’s roommate Mik is a Geek(also a Kim fan), he hacked the manager’s computer and get the timetable of the manager, and tell Kim when will the manager come to their room tomorrow. A big E-sport Event is around the corner, so Kim list m skills he should practice, each skill takes some time to practice and improve Kim’s skill by some points. You should calculate the max total improvement points Kim can get. Note any skills can be practiced any times , including 0.
The first line contains a integer T ( T <= 10 ), then T cases follows.
In each case, there are 3 parts of input.
The first part contains 3 integers L, n, m in a single line.Range[0, L] is the time Kim decide to practice , n is the times manager would enter his room, m indicate the total number of the skills.
The second part contains n integers ti(0 <= ti <= L) in a single line, means the manager would enter his room at ti. Note that ti is giving in the increasing order.
The third part has m lines , each line contains two integers ci, vi, means this skill needs ci minutes to practice and can make vi points improvement.
L<=500, n<=10, m<=100.
For each case, you should output the max points Kim can improve.
2
6 1 3
3
2 3
2 4
2 5
6 2 3
2 4
2 3
2 4
2 5
10
15
Note that Kim will be catch playing games any time in the interval of his practicing, excluded the beginning and the ending of each practice time.
题意:一个同学想要在上自习的时候练武功,为了提升自己的战斗力,但是老师会查班,为了不让老师发现,他通过某种方法知道了老师在什么时候查班,问他最终可以获得的最大战斗力是多少。。。三个数 l,n,m,l代表的是这个学生从0这个时间点到 l 这个时间点可以练功,n表示的是接下来一行有 n个数,n个数的值代表的是老师会在那个时间点来查班,接下来m行,每行两个数,第一个数代表的是练这种武功花费的时间,第二个数是练这种武功可以提升的战斗力,问这个同学可以获得的最大战斗力
思路:完全背包题,但要根据老师来查班的时间把时间段分成好几个段,然后分别求最大,然后求和就行了
#include
#include
#include
using namespace std;
int v[100005],dp[150000];
struct uuu
{
int u,w;
}s[1050000];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
memset(v,0,sizeof(v));
int l,n,m,sum=0,g,f;
scanf("%d%d%d",&l,&n,&m);
for(int a=1;a<=n;a++)
{
scanf("%d",&g);
v[g]=1;
}
for(int a=1;a<=m;a++)
{
scanf("%d%d",&s[a].u,&s[a].w);
}
int r=0;
for(int a=1;a<=l;a++)
{
if(v[a]==1||a==l) //把老师来查班的时间分开,分成几个时间段分别求出最大
{
int i=a-r;
r=a;
int maxx=0;
for(int j=1;j<=m;j++)
{
for(int b=1;b<=i;b++)
{
if(s[j].u<=b)
{
dp[b]=max(dp[b],dp[b-s[j].u]+s[j].w);
}
}
f=dp[i];//此时间段可以提升的最大战斗力
}
sum+=f; //sum最后求的是全部时间段的最大值之和
}
}
printf("%d\n",sum);
}
return 0;
}