喜欢玩warcraft的ltl

时间限制:2000 ms  |  内存限制:65535 KB
难度:3
描写叙述

ltl 很喜欢玩warcraft。由于warcraft十分讲究团队总体实力,而他自己如今也为升级而不拖累团队而努力。

他如今有非常多个地点来选择去刷怪升级,可是在每个地点他都要买上充足的补给和合适的道具。以免在刷怪的时候被怪物反杀了。每个地点的怪物打完了就没有了(还竟然不掉金钱跟装备),并且他仅仅要选定了地点就一定会刷完该地点所有的怪物,同一时候获得相应的经验值。如今ltl 能给出每个地点用来买补给和道具的钱和打完所有怪物所能获得的经验。可是他所拥有的钱是一定的。

所以他想知道怎么选择地点使得他获得的经验最高。

输入
第一行一个整数T,表示測试数据的组数 0<T<=10

第二行两个整数N,M,0<N<=100,0<M<=1000000表示ltl拥有N个不同地点的选择和M的金钱总数

接下来N行每行两个整数ci,vi,(0<ci<=1000000,0<vi<=2000)表示ltl刷完第i个地点所须要购买补给和道具的总钱数和能获取的总经验值
输出
一行一个整数。表示ltl可以获取的最大的经验值
例子输入
2
3 10
7 7
2 3
3 5
2 5
3 5
2 1
例子输出
Max experience: 12
Max experience: 6
读完题,立刻断定01背包问题。然后直接写代码,不幸的是,TLE不期而至!
超时代码:
#include<stdio.h>
struct node
{
int c;
int w;
}num[105];
int dp[1000005];
int Max(int a,int b)
{
return a>b? a:b;
}
int main()
{
int T,n,m;
int i,j;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
scanf("%d%d",&num[i].c,&num[i].w);
}
for(i=0;i<n;i++)
{
for(j=m;j>=num[i].c;j--)
{
dp[j]=Max(dp[j],dp[j-num[i].c]+num[i].w);
}
}
printf("Max experience: %d\n",dp[m]);
}
return 0;
}

下面为优化代码:

#include<stdio.h>
struct node
{
int c;
int w;
}num[105];
int dp[1000005];
int Max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int T,n,m;
int i,j,s,count;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
s=0;
for(i=0;i<n;i++)
{
scanf("%d%d",&num[i].c,&num[i].w);
s+=num[i].c;
}
for(i=0;i<=m;i++)
dp[i]=0;
for(i=0;i<n;i++)
{
s-=num[i].c;
count=Max(m-s,num[i].c);
for(j=m;j>=count;j--)
{
dp[j]=Max(dp[j],dp[j-num[i].c]+num[i].w);
}
}
printf("Max experience: %d\n",dp[m]);
}
return 0;
}

05-23 06:07