题目链接:点击打开链接
Lotus and Characters
Accepts: 150
Submissions: 897
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 262144/131072 K (Java/Others)
问题描述
Lotus有n种字母,给出每种字母的价值以及每种字母的个数限制,她想构造一个任意长度的串。 定义串的价值为:第1位字母的价值*1+第2位字母的价值*2+第3位字母的价值*3…… 求Lotus能构造出的串的最大价值。(可以构造空串,因此答案肯定≥0)
输入描述
第一行是数据组数T(0≤T≤1000)。 对于每组数据,第一行一个整数n(1≤n≤26),接下来n行,每行2个整数vali,cnti(∣vali∣,cnti≤100),分别表示第i种字母的价值和个数限制。
输出描述
对于每组数据,输出一行一个整数,表示答案。
输入样例
2 2 5 1 6 2 3 -5 3 2 1 1 1
输出样例
35 5
又被 hack,~~~自己还是太水
思路:根据排序不等式,显然应该把字母从小往大放。 一种错误的做法是把正权值的字母取出来从前往后放。错误是因为 负权的也可能出现在答案中:放在最前面来使后面每个字母的贡献都增加。 正确的做法是把字母从大往小从后往前放,如果加入该字母后答案变劣就停下来。注意一下特例:
输入:
3
-1 3
2 1
1 1
输出:
8【最优串为:-1,-1,-1,1,2】
输入:
2
-1 5
4 2
输出:
37 【最优串为:-1,-1,-1,-1,-1,4,4】
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int val[50];
int a[5000];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int num=0;
for(int i=1;i<=n;i++)
{
int x;
scanf("%d%d",&val[i],&x);
while(x--)
a[num++]=val[i];
}
sort(a,a+num);
int last=0,ans=0;
for(int i=num-1;i>=0;i--)
{
last+=a[i];
if(last<0)
break;
ans+=last;
}
printf("%d\n",ans);
}
return 0;
}
题目链接:点击打开链接
Lotus and Horticulture
Accepts: 91
Submissions: 641
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 262144/262144 K (Java/Others)
问题描述
这几天Lotus对培养盆栽很感兴趣,于是她想搭建一个温室来满足她的研究欲望。 Lotus将所有的n株盆栽都放在新建的温室里,所以所有盆栽都处于完全相同的环境中。 每一株盆栽都有一个最佳生长温度区间[l,r],在这个范围的温度下生长会生长得最好,但是不一定会提供最佳的研究价值(Lotus认为研究发育不良的盆栽也是很有研究价值的)。 Lotus进行了若干次试验,发现若第i株盆栽的生长温度适宜,可以提供ai的研究价值;若生长温度超过了适宜温度的上限,能提供bi的研究价值;若生长温度低于适宜温度的下限,则能提供ci的研究价值。 现在通过试验,Lotus已经得知了每一株盆栽的适宜生长温度范围,也知道了它们的a、b、c的值。你需要根据这些信息,给温室选定一个温度(这个温度可以是任意实数),使得Lotus能获得的研究价值最大。
输入描述
多组数据,第一行一个整数T表示数据组数 每组数据第一行一个整数n∈[1,50000],表示盆栽数量 接下来n行每行五个整数li,ri,ai,bi,ci∈[1,109],意义如上所述
输出描述
每组数据输出一行一个整数表示答案
输入样例
1 5 5 8 16 20 12 10 16 3 13 13 8 11 13 1 11 7 9 6 17 5 2 11 20 8 5
输出样例
83
思路:
#include<iostream>
#include<algorithm>
#include<cstring>
#define LL long long
using namespace std;
typedef pair<LL,LL> pll;
LL n,l,r,x1,x2,x3;
pll a[50000*3+10];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld",&n);
int num=0;
for(int i=1;i<=n;i++)
{
scanf("%lld%lld%lld%lld%lld",&l,&r,&x2,&x3,&x1);
l<<=1; r<<=1;
a[++num]=make_pair(0,x1);
a[++num]=make_pair(l,x2-x1);
a[++num]=make_pair(r+1,x3-x2);
}
sort(a+1,a+num+1);
a[0].first=-1;
LL last=0,ans=0;
for(int i=1;i<=num;i++)
{
if(a[i].first!=a[i-1].first)
ans=max(ans,last);
last+=a[i].second;
}
printf("%lld\n",max(ans,last)); // 这里为了保险起见,再求一次 max
}
return 0;
}