PDSUACM第六次比赛B题(令人头痛的题)

最近,瓦西亚决定提高他的手枪射击技能。今天,他的教练为他提供了以下锻炼。他在桌子上连续放置了n个罐头。罐从1到n从左到右编号。 Vasya必须将每个罐子击倒一次才能完成练习。允许他选择将罐子打倒的顺序。 Vasya知道ii罐的耐久性是ai。这意味着,如果Vasya已经将x罐击倒,并且现在准备开始射击第i罐,那么他将需要(ai⋅x+ 1)枪才能将其击倒。您可以假设,如果Vasya开始射击ii-罐,他将一直射击直到将其击倒。 您的任务是选择这样的射击顺序,以使将给定的n个罐中的每个精确击倒一次所需的射击次数最小化。

输入

输入的第一行包含一个整数nn(2≤n≤1000)-罐数。 输入的第二行包含序列a1,a2,…,ana1,a2,…,an(1≤ai≤1000),其中ai是第i个罐的耐用性。

输出

在第一行打印中,将给定的n个罐中的每一个准确地击倒一次所需的最少射击次数。
在第二行打印中,由n个从1到n的整数组成的序列-罐的索引顺序使所需的注射次数最小化。如果有多个答案,则可以打印其中任何一个。

Examples

Input
3
20 10 20
Output
43
1 3 2

Input
4
10 10 10 10
Output
64
2 1 4 3

Input
6
5 4 5 4 4 5
Output
69
6 1 3 5 2 4

Input
2
1 4
Output
3
2 1

注释

在第一个示例中,Vasya可以从第一个罐头开始射击。他以第一枪将其击倒,因为他之前没有击倒任何其他罐头。之后,他必须射击第三罐。为了击倒它,他射击了20⋅1+ 1 =21次。在那之后仅剩一秒钟。瓦萨亚击倒它的次数是10⋅2+ 1 =21次。因此,总拍摄数量为1 + 21 + 21 = 43。 在第二个示例中,拍摄顺序无关紧要,因为所有罐子都具有相同的耐用性。

这道题当时绕了我好久,得有半个小时啊啊啊啊,交错了四次,搞得我很崩溃。

#include <iostream>
#include <cstdio>
#include <algorithm>
// *start on @date: 2020-02-14 14:20 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int maxn = -999999;
int minn = 999999;

int main()
{
    int i,j,k,m,n,sum=0;
    cin >> m;
    int ff=0;
    int tem = 0;
    int s[1001]={0};
    int x[1001]={0};
    j=m;
    while(m--)
    {
        cin >> k;
        s[k]++;
        x[ff++]=k;
    }

    int flag[1001]={0};
    n=0; int p = 0;
    for(i=1000;i>=0;i--)
    if(s[i]!=0)
    {
        for(p=0;p<j;p++)
                {
                    if(x[p]==i)
                   { flag[tem++]=p;
                        x[p]=-5;
                        break;
                    }
                }
        s[i]--;
        break;
    }
    k = 1;
    for(i=1000;i>=0;i--)
    {
        if(s[i]!=0)
        {
                for(p=0;p<j;p++)
                {
                    if(x[p]==i)
                    {
                        flag[tem++]=p;
                        x[p]=-5;
                        
                        break;
                    }
                }
                s[i]--;
                sum = sum + (k*i+1);
                i++;k++;
        }
    }
    cout << sum+1<<endl;
    for(i=0;i<j;i++)
    {
        cout << flag[i]+1;
        if(i!=j-1)
        cout <<' ';
    }
    cout <<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值