題目:戳這裏c++
題意:n個數,兩種操做,第一種是a[i]*a[j],刪掉a[i],第一種是直接刪除a[i](只能用一次)剩下的數序列號不變。操做n-1次,使最後剩下的那個數最大化。ide
解題思路:url
正數之間全用操做1獲得的結果最大。spa
負數的個數若是是偶數,全用操做1最後獲得的也最大。若是是奇數,那最大的那個負數(貪心的思想)就要進行特殊操做,具體怎麼操做要看後面有沒有0,若是有0就用操做1去乘,沒有就用操做2直接給這個數刪了。.net
有0的話就把全部的0乘最後一個0,而後把最後一個0刪了。code
附ac代碼:blog
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 5e5 + 10; 5 const int inf = 5e5 + 10; 6 struct nod 7 { 8 ll a; 9 int id; 10 }nu[maxn]; 11 bool cmp(nod x, nod y) 12 { 13 return x.a < y.a; 14 } 15 int main() { 16 int n; 17 scanf("%d", &n); 18 for(int i = 1; i <= n; ++i) 19 { 20 scanf("%lld", &nu[i].a); 21 nu[i].id = i; 22 } 23 sort(nu + 1, nu + 1 + n, cmp); 24 int cntm = 0; 25 int lastz = 0; 26 int cntop = 0; 27 int firstp = 0; 28 int firstz = 0; 29 30 for(int i = 1; i <= n; ++i) 31 { 32 if(nu[i].a < 0) ++cntm; 33 if(nu[i].a == 0) 34 { 35 if(!firstz) firstz = i; 36 lastz = i; 37 } 38 if(nu[i].a > 0) 39 { 40 firstp = i; 41 break; 42 } 43 } 44 if(cntm & 1) 45 { 46 if(lastz) firstz = cntm; 47 else printf("2 %d\n", nu[cntm].id); 48 --cntm; 49 } 50 for(int i = 1; i < cntm; ++i) 51 { 52 printf("1 %d %d\n", nu[i].id, nu[cntm].id); 53 } 54 for(int i = firstz; i < lastz; ++i) 55 { 56 printf("1 %d %d\n", nu[i].id, nu[i + 1].id); 57 } 58 if(lastz && (cntm || firstp))//這裏wa了好多發 59 { 60 printf("2 %d\n", nu[lastz].id); 61 62 } 63 if(firstp) 64 { 65 if(cntm) 66 { 67 printf("1 %d %d\n", nu[cntm].id, nu[n].id); 68 } 69 for(int i = firstp; i < n; ++i) 70 { 71 printf("1 %d %d\n", nu[i].id, nu[n].id); 72 } 73 } 74 return 0; 75 }