题意:
有n个房间,要在T天内建造。每个房间都有建造所需时间ti和面积si,当建造完成时,获得的金币是t×si(t为开始建造这个房间时的剩余时间)。如果一个房间建造完后剩余时间已经为负了,那这个房间不给钱。
题解:
首先按si/ti排序(用乘法)。由于有可能不能全部建完,所以不能直接贪心,要用背包(见下面两个样例)。
2 200
100 200
200 400
3 1000
500 500
600 600
499 498
//Time:380ms
//Memory:252KB
//Length:954B
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define MAXN 3005
#define MAXM 10010
#define INF 100000007
#define EPS 1e-8
int t[MAXN],s[MAXN];
int ord[MAXN];
bool cmp(const int &a,const int &b)
{
if(s[a]*t[b]!=s[b]*t[a])
return s[a]*t[b]>s[b]*t[a];
else return s[a]>s[b];
}
int dp[MAXM];
int main()
{
//freopen("/home/moor/Code/input","r",stdin);
int n,tim,ans;
while(scanf("%d%d",&n,&tim)==2)
{
ans=0;
int tt=tim;
for(int i=1;i<=n;++i) scanf("%d%d",&t[i],&s[i]),ord[i]=i;
sort(ord+1,ord+n+1,cmp);
memset(dp,0,sizeof(dp));
for(int i=n;i>=1;--i)
for(int j=tim-t[ord[i]];j>=0;--j)
{
dp[j+t[ord[i]]]=max(dp[j+t[ord[i]]],dp[j]+s[ord[i]]*(j+t[ord[i]]));
ans=max(ans,dp[j+t[ord[i]]]);
}
printf("%d\n",ans);
}
return 0;
}