[2020牛客多校第一場][D. Quadratic Form]


題目鏈接:https://ac.nowcoder.com/acm/contest/5666/D

題目大意:給定一實正定二次型矩陣\(A\),求當\(\sum_{i=1}^n\sum_{j=1}^{n}A_{ij}x_ix_j\le 1\),即\(x^TAx \le 1\)時,\(\sum_{i=1}^n b_ix_i\)的最大值

題解:由於\(A\)是實正定二次型,所以我們可以大概猜測當\(\sum_{i=1}^n b_ix_i\)取到最值時,有\(x^TAx - 1= 0\)成立。將其看為約束條件,現在要求\(f(x_1,x_2,...,x_n)=\sum_{i=1}^n b_ix_i\)的最值,可以考慮使用拉格朗日乘數法。

   令\(g(x_1,x_2,...,x_n,\lambda)=\sum_{i=1}^n b_ix_i+\lambda(\sum_{i=1}^n\sum_{j=1}^{n}A_{ij}x_ix_j- 1)\),對各自變量求偏導可以得出取得最值的條件為

\begin{cases}
b_1+\lambda(2A_{11}x_1+2A_{12}x_2+...+2A_{1n}x_n)=0\\
b_2+\lambda(2A_{21}x_1+2A_{22}x_2+...+2A_{2n}x_n)=0\\
......\\
b_n+\lambda(2A_{n1}x_1+2A_{n2}x_2+...+2A_{nn}x_n)=0\\
\sum_{i=1}^n\sum_{j=1}^{n}A_{ij}x_ix_j- 1=0
\end{cases}

   化簡為矩陣形式就是

\begin{cases}
B+2\lambda Ax=0\\
x^TAx=1
\end{cases}

   而我們要求的答案就是\(ans=\sum_{i=1}^n b_ix_i=B^Tx=x^TB\)

   由第一個式子我們可以通過移項得到\(2\lambda Ax=-B\),左乘\(\frac{A^{-1}}{2\lambda}\)得出\(x=-\frac{A^{-1}B}{2\lambda}\)

   因此\(B^Tx=-\frac{1}{2\lambda}B^TA^{-1}B=x^TB\),同時也能得到\(x^T=-\frac{1}{2\lambda}B^TA^{-1}\)

   將\(x=-\frac{A^{-1}B}{2\lambda}\)與\(x^T=-\frac{1}{2\lambda}B^TA^{-1}\)同時代入式子\(x^TAx=1\)可得出

$$-\frac{1}{2\lambda}B^TA^{-1}\cdot  A\cdot (-\frac{A^{-1}B}{2\lambda})=1$$

   即

$$\frac{1}{4\lambda ^2}B^TA^{-1}B=1$$

   再根據我們之前得到的\(ans=B^Tx=-\frac{1}{2\lambda}B^TA^{-1}B\),我們要輸出的\(ans^2\)就是

$$(-\frac{1}{2\lambda}B^TA^{-1}B)^2=\frac{1}{4\lambda ^2}(B^TA^{-1}B)\cdot(B^TA^{-1}B)=B^TA^{-1}B$$

   套用矩陣求逆的板子即可通過此題

 

#include<bits/stdc++.h>
using namespace std;
#define N 510
#define LL long long
#define MOD 998244353
LL n,a[N][N],b[N];
LL qow(LL x,LL y){return y?(y&1?x*qow(x,y-1)%MOD:qow(x*x%MOD,y/2)):1;}
int main()
{
    while(~scanf("%lld",&n))
      {
      LL res=0;
      for(LL i=1;i<=n;i++)
        {
        for(LL j=1;j<=n;j++)
          scanf("%lld",&a[i][j]),a[i][n+j]=0;
        a[i][n+i]=1;
        }
      for(LL i=1;i<=n;i++)scanf("%lld",&b[i]);
      for(LL i=1;i<=n;i++)
        {
        LL id=-1;
        for(LL j=i;j<=n;j++)if(a[j][i]){id=j;break;}
        swap(a[i],a[id]);
        LL t=qow(a[i][i],MOD-2);
        for(LL j=i;j<=2ll*n;j++)a[i][j]=a[i][j]*t%MOD;
        for(LL j=i+1;j<=n;j++)
          for(LL k=2ll*n;k>=i;k--)
            a[j][k]=(a[j][k]+MOD-a[i][k]*a[j][i]%MOD)%MOD;
        }
      for(LL i=n;i>=1;i--)
        for(LL j=i-1;j>=1;j--)
          for(LL k=2ll*n;k>=i;k--)
            a[j][k]=(a[j][k]+MOD-a[i][k]*a[j][i]%MOD)%MOD;
      for(LL i=1;i<=n;i++)
        for(LL j=1;j<=n;j++)
          res=(res+b[i]*b[j]%MOD*a[i][n+j])%MOD;
      printf("%lld\n",res);
      }
}
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM