E. Two Arrays and Sum of Functions(贪心)

题目链接:https://codeforces.com/problemset/problem/1165/E

题目大意:

n代表n个数,然后输入a数组,a数组有n个,b数组有n个。然后你可以对b数组里面的数任意排序,最终目的是使得题目中的表达式的值尽可能的小。

具体思路:

贪心,假设我们当前n==2.a数组分别是 1 5 ,b数组分别是 4 5 。我们如果让表达式尽可能小,就尽量让大的数去乘一个小的数,然后让一个小的数去乘一个大的数,这样获得的结果

是尽可能的小的。然后对于题目中表达式的求解,通过打表能发现,每个位置的相乘次数是固定的,也就是一个以中心对称,单边单调递减的。

AC代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 # define ll unsigned  long long
  4 # define inf 0x3f3f3f3f
  5 const int maxn = 2e5+100;
  6 const ll mod = 998244353 ;
  7 struct node
  8 {
  9     ll num;
 10     ll id;
 11     node() {}
 12     node(ll xx,ll yy)
 13     {
 14         num=xx,id=yy;
 15     }
 16     bool friend operator < (node t1,node t2)
 17     {
 18         return t1.num<t2.num;
 19     }
 20 } a[maxn],b[maxn];
 21 ll aa[maxn],bb[maxn],c[maxn];
 22 ll vis[maxn];
 23 bool cmp(node t1,node t2)
 24 {
 25     return t1.id<t2.id;
 26 }
 27 bool cmp1(ll t1,ll t2){
 28 return t1<t2;
 29 }
 30 bool cmp2(ll t1,ll t2){
 31 return t1>t2;
 32 }
 33 int main()
 34 {
 35    ll n;
 36     scanf("%lld",&n);
 37     for(ll i=1; i<=n; i++)
 38     {
 39         scanf("%lld",&a[i].num);
 40         a[i].id=i;
 41         aa[i]=a[i].num;
 42     }
 43     for(ll i=1; i<=n; i++)
 44     {
 45         scanf("%lld",&b[i].num);
 46         b[i].id=i;
 47         bb[i]=b[i].num;
 48     }
 49 //    sort(a+1,a+n+1);
 50 //    sort(b+1,b+n+1);
 51 //    for(ll i=1; i<=n; i++)
 52 //    {
 53 //        c[a[i].id]=b[n-i+1].num;
 54 //    }
 55 //    for(ll i=1; i<=n; i++)
 56 //    {
 57 //        bb[i]=c[i];
 58 //    }
 59 //    ll sum=0;
 60 //    for(int i=1; i<=n; i++)
 61 //    {
 62 //        for(int j=i; j<=n; j++)
 63 //        {
 64 //            ll tmp=0;
 65 //            for(int k=i; k<=j; k++)
 66 //            {
 67 //                vis[k]++;
 68 //                tmp=tmp+aa[k]*bb[k]%mod;
 69 //                tmp%=mod;
 70 //            }
 71 //            tmp%=mod;
 72 //            sum+=tmp;
 73 //            sum%=mod;
 74 //        }
 75 //    }
 76 //    for(int i=1;i<=n;i++){
 77 //    cout<<i<<" "<<vis[i]<<endl;
 78 //    }
 79 //    cout<<endl;
 80 //   memset(vis,0,sizeof(vis));
 81     ll tmp=n-2ll;
 82     vis[1]=n;
 83     for(ll i=2; i<=(n+1)/2; i++)
 84     {
 85         vis[i]=vis[i-1]+tmp;
 86         tmp-=2ll;
 87     }
 88     for(ll i=(n+1)/2+1; i<=n; i++)
 89     {
 90         vis[i]=vis[n-i+1];
 91     }
 92       for(int i=1; i<=n; i++)
 93     {
 94         aa[i]*=vis[i];// 注意这里是aa数组先乘上出现次数再去排序,不能先排序再去相乘 ,否则有可能不是最优结果
 95     }
 96     sort(aa+1,aa+n+1,cmp1);
97 sort(bb+1,bb+n+1,cmp2); 98 // for(int i=1;i<=n;i++){ 99 // cout<<aa[i]<<" "; 100 // } 101 // cout<<endl; 102 // for(int i=1;i<=n;i++){ 103 // cout<<bb[i]<<" "; 104 // } 105 // cout<<endl; 106 107 ll sum=0; 108 for(ll i=1; i<=n; i++) 109 { 110 sum= sum+(aa[i]%mod*bb[i]%mod)%mod; 111 sum%=mod; 112 } 113 sum%=mod; 114 printf("%lld ",sum); 115 return 0; 116 }
原文地址:https://www.cnblogs.com/letlifestop/p/10908504.html