D. Quadratic Form
题目描述
  Bobo has a positive-definite  matrix 
 and an 
-dimension vector 
. He would like to find 
 where 
, 
 and 
 is maximum.
  It can be shown that , which is rational.
  Find the value of .  
输入描述
  The input consists of several test cases terminated by end-of-file.
  The first line of each test case contains an integer .
  The -th of the following 
 lines contains 
 integers 
.
  The last line contains  integers 
.
  , 
,
.
  , for any 
.
  .
  The sum of  does not exceed 
.   
输出描述
For each test case, print an integer which denotes the result.
示例1
输入
2
1 0
0 1
0 0
2
1 0
0 1
1 1
2
8 4
4 3
1 1
输出
0
2
623902721
分析
  将题目转化为约束条件下的最值问题。此处只讨论极值,不讨论边界可能存在的最值。
  考虑到约束条件  为不等式约束,可以添加 
 条件,利用拉格朗日乘数法求解。
  首先需要讨论矩阵  的一些性质。由于 
,故 
 可逆。根据 
 且 
,得 
 为实对称矩阵,继而 
 也为实对称矩阵。又有 
,故 
 为正定矩阵,继而 
 也为正定矩阵。上述性质都会在接下来的推导中涉及。
  定义:,
。  则有约束条件 
,要求最大值的表达式为 
 或 
。
  令 ;有 
 方程组如下。  
  将  方程组的第一式展开,得到如下方程组。    
  将上述方程组写成矩阵形式,有 。即 
,等式两边取转置,得 
;
,得 
。代入约束条件,移项后有 
, 
;由于 
 为正定矩阵,故 
;所以约束条件是有效的,即 
。根据式 
,可得到最优解为 
;将其带入式 
,有 
。
  由于 ,代入最优解 
,得 
 的最大值为 
。于是,
 最大值为 
;将式 
 代入,有 
。
  综上所述,最终答案为 。套用矩阵求逆模板和矩阵乘法公式即可。      
代码
/******************************************************************
Copyright: 11D_Beyonder All Rights Reserved
Author: 11D_Beyonder
Problem ID: 2020牛客暑期多校训练营(第一场) Problem D
Date: 7/22/2020 
Description: 
    Use lagrange multiplier method
    Compute the inverse matrix 
*******************************************************************/
#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
const int N=202;
const ll mod=998244353;
ll a[N][N<<1],b[N],c[N];
int n;
void inverse();
ll qpow_mod(ll a,int b);
int main()
{
    while(~scanf("%d",&n))
    {
        int i,j,k;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                scanf("%lld",&a[i][j]);
                a[i][n+j]=0;//初始化
                a[i][j]%=mod;
            }
        }
        for(i=1;i<=n;i++)
        {
            scanf("%lld",b+i);
            b[i]%=mod;
        }
        inverse();
        //=========================================
        //a[1][1+n]*b[1]+a[2][1+n]*b[2]...
        //a[2][1+n]*b[1]+a[2][1+n]*b[2]...
        //...
        for(j=1;j<=n;j++)
        {
            ll res=0;
            for(i=1;i<=n;i++)
            {
                res+=a[i][j+n]*b[i];
                res%=mod;
            }
            c[j]=res%mod;
        }
        //c存b的转置由乘A的结果
        //==========================================
        //计算c右乘B
        ll ans=0;
        for(i=1;i<=n;i++) 
        {
            ans+=b[i]*c[i];
            ans%=mod;
        }
        //==========================================
        printf("%lld\n",ans);
    }
    return 0;
}
void inverse()//矩阵求逆模板
{
    int m=n+n;
    int i,j,k;
    for(i=1;i<=n;i++) a[i][i+n]=1;
    for(i=1;i<=n;i++)
    {
        for(j=i;j<=n;j++)
        {
            if(a[j][i])
            {
                for(k=1;k<=m;k++)
                {
                    swap(a[i][k],a[j][k]);
                }
            }
        }
        ll r=qpow_mod(a[i][i],mod-2);
        for(j=i;j<=m;j++) a[i][j]=r*a[i][j]%mod;
        for(j=1;j<=n;j++)
        {
            if(i==j) continue;
            ll rate=a[j][i]*a[i][i]%mod;
            for(k=i;k<=m;k++) 
            {
                a[j][k]=a[j][k]-rate*a[i][k]%mod;
                a[j][k]=(a[j][k]%mod+mod)%mod;
            }
        }
    }
}
ll qpow_mod(ll a,int b)
{
    ll res=1;
    while(b)
    {
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
} 
京公网安备 11010502036488号