zoukankan      html  css  js  c++  java
  • [2020牛客多校第一场][D. Quadratic Form]

    题目链接:https://ac.nowcoder.com/acm/contest/5666/D

    题目大意:给定一实正定二次型矩阵(A),求当(sum_{i=1}^nsum_{j=1}^{n}A_{ij}x_ix_jle 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}^nsum_{j=1}^{n}A_{ij}x_ix_j- 1)),对各自变量求偏导可以得出取得最值的条件为

    egin{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}^nsum_{j=1}^{n}A_{ij}x_ix_j- 1=0
    end{cases}

       化简为矩阵形式就是

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

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

       由第一个式子我们可以通过移项得到(2lambda Ax=-B),左乘(frac{A^{-1}}{2lambda})得出(x=-frac{A^{-1}B}{2lambda})

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

       将(x=-frac{A^{-1}B}{2lambda})与(x^T=-frac{1}{2lambda}B^TA^{-1})同时代入式子(x^TAx=1)可得出

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

       即

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

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

    $$(-frac{1}{2lambda}B^TA^{-1}B)^2=frac{1}{4lambda ^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
    ",res);
          }
    }
    View Code
  • 相关阅读:
    ***:做人的基本原则(看完终身受益)
    ref和out的相同和不同的讨论
    关于继承和虚函数的入门讨论
    C#中利用ArrayList来对索引器访问越界情况进行内容的扩充处理
    [C#]实现IEnumerable接口来使用foreach语句的一个实例
    浅谈MSSQL锁机制
    jQuery图片分屏加载技术插件
    SET IDENTITY_INSERT [Table] [ON|OFF]
    SQL Server DATEPART() 函数
    常用的SQL语句对数据库进行操作
  • 原文地址:https://www.cnblogs.com/DeaphetS/p/13291266.html
Copyright © 2011-2022 走看看