CF1042C Array Product(贪心,模拟)

题目描述

You are given an array aa consisting of nn integers. You can perform the following operations with it:

  1. Choose some positions ii and jj ( 1 le i, j le n, i e j1i,jn,ij ), write the value of a_i cdot a_jaiaj into the jj -th cell and remove the number from the ii -th cell;
  2. Choose some position ii and remove the number from the ii -th cell (this operation can be performed no more than once and at any point of time, not necessarily in the beginning).

The number of elements decreases by one after each operation. However, the indexing of positions stays the same. Deleted numbers can't be used in the later operations.

Your task is to perform exactly n - 1n1 operations with the array in such a way that the only number that remains in the array is maximum possible. This number can be rather large, so instead of printing it you need to print any sequence of operations which leads to this maximum number. Read the output format to understand what exactly you need to print.

题目大意:

有n个数,组成一个数列,我们可以进行两种操作:

1 l r

表示 r=l∗r,同时删去l

2 w

表示删掉w这个位置的数(只能使用一次)

现在,你可以进行n−1次操作,并要求你在进行n−1次操作后使剩下的最后一个数最大。操作不会改变数字的序号(也就是删除一个数后后面的不会前移)。因为答案可能很大,我们不用输出最终结果,只需输出任意一种方案

思路:

贪心题。。

我们知道一点,任何一个0乘进来都没有什么用

因为任何一个数乘0都是0,一定不会最优

所以0是废物

同时负数呢?

负负得正

所以我们可以留下偶数个负数

如果负数是奇数个,那么很遗憾,为了不让最终结果是负数,必须要舍弃一个

乘积最大,所以要舍弃的,就是绝对值最小的那个

然后我们把要舍弃的先合并再舍弃

为什么呢?

比如说序列长为n,我的序列里全是0

如果你一个一个地删除,你就得删n次

而如果你两两合并呢?

答案是0,的确是最优情况了

Ok,不过细节不少,大家要多多注意

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rii register int i
#define rij register int j
using namespace std;
int n,a[200005],cnt,bj[200005],wz,zero[200005],minx=2147483647,bnt;
int main()
{
    scanf("%d",&n);
    for(rii=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]==0)
        {
            bnt++;
            zero[bnt]=i;
            bj[i]=1;
        }
        if(a[i]<0)
        {
            cnt++;
            if(-1*a[i]<minx)
            {
                minx=-1*a[i];
                wz=i;
            }
        }
    }
    if(cnt%2==1)
    {
        bj[wz]=1;
        bnt++;
        zero[bnt]=wz;
    }
    sort(zero+1,zero+bnt+1);
    int pre=zero[1];
    for(rii=2;i<=bnt;i++)
    {
        printf("1 %d %d
",pre,zero[i]);
        pre=zero[i]; 
    }
    if(bnt!=n&&bnt!=0)
    {
        printf("2 %d
",pre);
    }
    for(rii=1;i<=n;i++)
    {
        if(bj[i]!=1)
        {
            pre=i;
            break;
        }
    }
    for(rii=pre+1;i<=n;i++)
    {
        if(bj[i]==0)
        {
            printf("1 %d %d
",pre,i);
            pre=i;
        }
    }
}
原文地址:https://www.cnblogs.com/ztz11/p/9680972.html