zoukankan      html  css  js  c++  java
  • BZOJ 4004 JLOI2015 装备购买 高斯消元+线性基

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4004

    Description

    脸哥最近在玩一款神奇的游戏,这个游戏里有 n 件装备,每件装备有 m 个属性,用向量zi(aj ,.....,am) 表示(1 <= i <= n; 1 <= j <= m),每个装备需要花费 ci,现在脸哥想买一些装备,但是脸哥很穷,所以总是盘算着怎样才能花尽量少的钱买尽量多的装备。
    对于脸哥来说,如果一件装备的属性能用购买的其他装备组合出(也就是说脸哥可以利用手上的这些装备组合出这件装备的效果),那么这件装备就没有买的必要了。严格的定义是,如果脸哥买了 zi1,.....zip这 p 件装备,那么对于任意待决定的 zh,不存在 b1,....,bp 使得 b1zi1 + ... + bpzip = zh(b 是实数),那么脸哥就会买 zh,否则 zh 对脸哥就是无用的了,自然不必购买。
    举个例子,z1 =(1; 2; 3);z2 =(3; 4; 5);zh =(2; 3; 4),b1 =1/2,b2 =1/2,就有 b1z1 + b2z2 = zh,那么如果脸哥买了 z1 和 z2 就不会再买 zh 了。脸哥想要在买下最多数量的装备的情况下花最少的钱,你能帮他算一下吗?

    Input

    第一行两个数 n;m。接下来 n 行,每行 m 个数,其中第 i 行描述装备 i 的各项属性值。接下来一行 n 个数,其中 ci 表示购买第 i 件装备的花费。

    Output

    一行两个数,第一个数表示能够购买的最多装备数量,第二个数表示在购买最多数量的装备的情况下的最小花费。 

    Sample Input

    3 3
    1 2 3
    3 4 5
    2 3 4
    1 1 2

    Sample Output

    2 2

    HINT

    如题目中描述,选择装备 1 装备 2,装备 1 装备 3,装备 2 装备 3 均可,但选择装备 1 和装备 2 的花费最小,为 2。
    对于 100% 的数据:1 <= n;m <= 500,0 <= aj <= 1000.
     
     
    ——————————————————————————————————————————————————————
     
     

    题意概述:

    ·给出N个M维向量,选择向量i花费代价ci。求一个包含向量最多的线性无关组,使得选择这个无关组的代价最小。

    ·N,M<=500,ai<=1000(话说ci呢?)

    分析:

    ·可以把向量看成一个多元一次方程。如果一些方程相关,那么这些方程可以互相表示。

    ·考虑高斯消元过程,发现最终系数为0的方程能够被上面的一些方程表示出来,换言之不为0的向量一旦和这些向量相组合就不是线性无关,不符合要求。最终高斯消元剩下的非0的方程数量就是这个集合中的线性无关组数量。即一个向量集和的线性不相关向量数量是唯一确定的,并且和高斯消元后非0向量的数量相同。(可以YY两个线性相关向量集合在一起变成一个新集合的情况)

    ·解决了最大购买数的问题,那么最小代价?

    ·贪心,把所有的向量按照权值从小到大排序,然后直接消元,遇到当前向量关键维度的值为0的时候选择还没有考虑的向量中权值最小的那个作为现在的关键字,延后考虑当前向量。有了上面第一问的分析之后这个贪心显然是正确的。具体实现搞个链表什么的。

    ·最坑的地方还是精度......最后看精度没救了强行上了逆元来进行模意义下的运算,然而这好像就步入了玄学的领域......为了不冲突就只能在比较大的mo意义下搞事情然而有点慢啊......

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<queue>
     8 #include<set>
     9 #include<map>
    10 #include<vector>
    11 #include<cctype>
    12 using namespace std;
    13 const int maxn=505;
    14 const int mo=1000000007;
    15 typedef long long LL;
    16 
    17 int N,M,C[maxn],next[maxn];
    18 struct data{
    19     int id,v;
    20     friend bool operator < (data x,data y){
    21         return x.v<y.v;
    22     }
    23 }D[maxn];
    24 int A[maxn][maxn];
    25 
    26 void data_in()
    27 {
    28     scanf("%d%d",&N,&M);
    29     int x;
    30     for(int i=1;i<=N;i++)
    31     for(int j=1;j<=M;j++)
    32         scanf("%d",&A[i][j]);
    33     for(int i=1;i<=N;i++) scanf("%d",&C[i]);
    34 }
    35 void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
    36 {
    37     if(!b) d=a,x=1,y=0;
    38     else exgcd(b,a%b,d,y,x),y-=(a/b)*x;
    39 }
    40 int inv(int a)
    41 {
    42     LL x=0,y=0,d=0; exgcd(a,mo,d,x,y);
    43     return x;
    44 }
    45 int Gauss()
    46 {
    47     int p=next[0],i=1,last=0;
    48     while(p&&i<=M){
    49         if(!A[p][i]){
    50             int pp,_last=p;
    51             for(pp=next[p];pp;_last=pp,pp=next[pp]) if(A[pp][i]) break;
    52             if(!pp){ i++; continue; }
    53             next[_last]=next[pp],next[last]=pp,next[pp]=p;
    54             p=pp;
    55         }
    56         for(int pp=next[p];pp;pp=next[pp]){
    57             int t=1ll*A[pp][i]*inv(A[p][i])%mo;
    58             for(int j=i;j<=M;j++)
    59                 A[pp][j]=(A[pp][j]-1ll*A[p][j]*t%mo+mo)%mo;
    60         }
    61         last=p,p=next[p],i++;
    62     }
    63     return p;
    64 }
    65 void work()
    66 {
    67     for(int i=1;i<=N;i++) D[i]=(data){i,C[i]};
    68     sort(D+1,D+N+1);
    69     int p=0;
    70     for(int i=1;i<=N;i++) next[p]=D[i].id,p=D[i].id;
    71     next[p]=0;
    72     int P=Gauss(),ans1=0,ans2=0;
    73     for(p=next[0];p!=P;p=next[p]) ans1++,ans2+=C[p];
    74     printf("%d %d
    ",ans1,ans2);
    75 }
    76 int main()
    77 {
    78     data_in();
    79     work();
    80     return 0;
    81 }
  • 相关阅读:
    【36氪收录】观「招商银行」隐私计算布局的思考
    如何用cmake编译
    docker | Ubuntu16.04安装与卸载docker
    通过删除注册表重新获得软件试用期
    k8s | 重启Kubernetes Pod的几种方式
    2021年终总结(一)
    凡是过往、皆为序章20210917PPT分享
    多厂商容器平台开发系统性总结
    VS2022安装.NetFramework4.0目标包的方法
    C# Winform窗体继承过程中,TableLayoutPanel是不支持继承的
  • 原文地址:https://www.cnblogs.com/KKKorange/p/8617113.html
Copyright © 2011-2022 走看看