这是一道水题,不过还挺有趣的,主要就是找规律。
-----------------------------------------------------------------------------------------
重新提示一下下面符号的意义
N代表有多少个数 P代表有多少个+号 Q代表有多少个-号 K代表有多少个括号
Ai代表数据
输入数据|K为0时算式最大值|K为1时算式最大值|...|K为N时算式最大值|
2 1 0 K=0 K=1 K>=2等等情况
1 2 2+1=3 *//星号代表括号再多也是上一种情况的值
2 0 1
1 2 2-1=1 *
3 2 0
1 2 3 3+2+1=6 *
3 0 2
1 2 3 3-1-2=0 [3-(1-2)=4 *](Q>=2,K>=1//当减号>=2和括号>=1时的情况)
3 1 1
1 2 3 3+2-1=4 *
4 3 0
1 2 3 4 4+3+2+1=10 *
4 0 3
1 2 3 4 4-1-2-3=-2 [4-(1-2-3)=8 *](Q>=2,K>=1//当减号>=2和括号>=1时的情况)
4 2 1
1 2 3 4 4+3+2-1=8 *
4 1 2
1 2 3 4 4+3-1-2=4 [4+3-(1-2)=8 *](Q>=2,K>=1//当减号>=2和括号>=1时的情况)
由此我们可以观察出一个规律
设:
N P Q K
Ai:A1...AN
我们可以看到结果值主要取决于括号和减号,所以可以分两种情况去计算
一:(Q<2,K可任取)或者(Q=2,K<1)
max + -(把最大值取出来加到结果里,然后一个+号对应一个值加到求和结果里(大值优先对应),之后剩下来的值都是一些小的了,然后一个-号对应一个值把求和结果给减去那个值(小值优先对应优先))
二:(Q>=2,K>=1)
max + |-| -min(把最大值取出来加到结果里,然后一个+号对应一个值加到求和结果里(大值优先对应),之后剩下来的值都是一些小的了,之后把最小值拿出来用求和结果减去这个值,剩下来的是是一些小的值了(不包括最小的值,因为最小的值咱们刚才给取出来了),然后一个-号对应一个值把这个值进行求绝对值了加到那个求和结果里(小值优先对应))
-----------------------------------------------------------------------------------------
最后的那个求和结果就是咱们要的那个结果了,这题比较简单,观察规律即可,下面是c++的代码。
#include <iostream>
#include <algorithm>
using namespace std;
const int M=100000;
int a[M];
bool compare(int a,int b){return a>b;}
int main()
{
int N,P,Q,K,sum=0;
while(1)
{
sum=0;
cin>>N>>P>>Q>>K;
for(int i=0;i<N;i++)cin>>a[i];
sort(a,a+N,compare);//排序函数,compare是排序规则,从大到小。
if(Q>=2&&K>=1)//看上面最后总结的规律
{
sum+=a[0];//这些都是sum的计算
for(int i=1;i<=P;i++)sum+=a[i];
for(int i=P+1;i<=P+Q-1;i++)sum+=a[i];
sum-=a[N-1];
}
else
{
sum+=a[0];
for(int i=1;i<=P;i++)sum+=a[i];
for(int i=P+1;i<=P+Q;i++)sum-=a[i];
}
cout<<sum<<endl;
}
return 0;
}