BZOJ 4004 JLOI2015 装备购买 高斯消元+线性基
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4004
Description
Input
Output
一行两个数,第一个数表示能够购买的最多装备数量,第二个数表示在购买最多数量的装备的情况下的最小花费。
Sample Input
1 2 3
3 4 5
2 3 4
1 1 2
Sample Output
HINT
题意概述:
·给出N个M维向量,选择向量i花费代价ci。求一个包含向量最多的线性无关组,使得选择这个无关组的代价最小。
·N,M<=500,ai<=1000(话说ci呢?)
分析:
·可以把向量看成一个多元一次方程。如果一些方程相关,那么这些方程可以互相表示。
·考虑高斯消元过程,发现最终系数为0的方程能够被上面的一些方程表示出来,换言之不为0的向量一旦和这些向量相组合就不是线性无关,不符合要求。最终高斯消元剩下的非0的方程数量就是这个集合中的线性无关组数量。即一个向量集和的线性不相关向量数量是唯一确定的,并且和高斯消元后非0向量的数量相同。(可以YY两个线性相关向量集合在一起变成一个新集合的情况)
·解决了最大购买数的问题,那么最小代价?
·贪心,把所有的向量按照权值从小到大排序,然后直接消元,遇到当前向量关键维度的值为0的时候选择还没有考虑的向量中权值最小的那个作为现在的关键字,延后考虑当前向量。有了上面第一问的分析之后这个贪心显然是正确的。具体实现搞个链表什么的。
·最坑的地方还是精度......最后看精度没救了强行上了逆元来进行模意义下的运算,然而这好像就步入了玄学的领域......为了不冲突就只能在比较大的mo意义下搞事情然而有点慢啊......
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<cstdlib>
- #include<algorithm>
- #include<cmath>
- #include<queue>
- #include<set>
- #include<map>
- #include<vector>
- #include<cctype>
- using namespace std;
- const int maxn=;
- const int mo=;
- typedef long long LL;
- int N,M,C[maxn],next[maxn];
- struct data{
- int id,v;
- friend bool operator < (data x,data y){
- return x.v<y.v;
- }
- }D[maxn];
- int A[maxn][maxn];
- void data_in()
- {
- scanf("%d%d",&N,&M);
- int x;
- for(int i=;i<=N;i++)
- for(int j=;j<=M;j++)
- scanf("%d",&A[i][j]);
- for(int i=;i<=N;i++) scanf("%d",&C[i]);
- }
- void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
- {
- if(!b) d=a,x=,y=;
- else exgcd(b,a%b,d,y,x),y-=(a/b)*x;
- }
- int inv(int a)
- {
- LL x=,y=,d=; exgcd(a,mo,d,x,y);
- return x;
- }
- int Gauss()
- {
- int p=next[],i=,last=;
- while(p&&i<=M){
- if(!A[p][i]){
- int pp,_last=p;
- for(pp=next[p];pp;_last=pp,pp=next[pp]) if(A[pp][i]) break;
- if(!pp){ i++; continue; }
- next[_last]=next[pp],next[last]=pp,next[pp]=p;
- p=pp;
- }
- for(int pp=next[p];pp;pp=next[pp]){
- int t=1ll*A[pp][i]*inv(A[p][i])%mo;
- for(int j=i;j<=M;j++)
- A[pp][j]=(A[pp][j]-1ll*A[p][j]*t%mo+mo)%mo;
- }
- last=p,p=next[p],i++;
- }
- return p;
- }
- void work()
- {
- for(int i=;i<=N;i++) D[i]=(data){i,C[i]};
- sort(D+,D+N+);
- int p=;
- for(int i=;i<=N;i++) next[p]=D[i].id,p=D[i].id;
- next[p]=;
- int P=Gauss(),ans1=,ans2=;
- for(p=next[];p!=P;p=next[p]) ans1++,ans2+=C[p];
- printf("%d %d\n",ans1,ans2);
- }
- int main()
- {
- data_in();
- work();
- return ;
- }
BZOJ 4004 JLOI2015 装备购买 高斯消元+线性基的更多相关文章
- BZOJ 4004: [JLOI2015]装备购买 高斯消元解线性基
BZOJ严重卡精,要加 $long$ $double$ 才能过. 题意:求权和最小的极大线性无关组. 之前那个方法解的线性基都是基于二进制拆位的,这次不行,现在要求一个适用范围更广的方法. 考虑贪心 ...
- BZOJ 4004: [JLOI2015]装备购买 [高斯消元同余 线性基]
和前两(一)题一样,不过不是异或方程组了..... 然后bzoj的新数据是用来卡精度的吧..... 所有只好在模意义下做啦 只是巨慢无比 #include <iostream> #incl ...
- bzoj 4004 [JLOI2015]装备购买——拟阵证明贪心+线性基
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4004 看Zinn博客水过去…… 运用拟阵可以证明按价格从小到大买的贪心是正确的.但自己还不会 ...
- 高斯消元 & 线性基【学习笔记】
高斯消元 & 线性基 本来说不写了,但还是写点吧 [update 2017-02-18]现在发现真的有好多需要思考的地方,网上很多代码感觉都是错误的,虽然题目通过了 [update 2017- ...
- bzoj 4004: [JLOI2015]装备购买 拟阵 && 高消
4004: [JLOI2015]装备购买 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 337 Solved: 139[Submit][Status ...
- BZOJ 4004: [JLOI2015]装备购买
4004: [JLOI2015]装备购买 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1154 Solved: 376[Submit][Statu ...
- bzoj 4004 [JLOI2015]装备购买 拟阵+线性基
[JLOI2015]装备购买 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1820 Solved: 547[Submit][Status][Dis ...
- BZOJ 2844 albus就是要第一个出场 ——高斯消元 线性基
[题目分析] 高斯消元求线性基. 题目本身不难,但是两种维护线性基的方法引起了我的思考. void gauss(){ k=n; F(i,1,n){ F(j,i+1,n) if (a[j]>a[i ...
- 洛谷P3389 高斯消元 / 高斯消元+线性基学习笔记
高斯消元 其实开始只是想搞下线性基,,,后来发现线性基和高斯消元的关系挺密切就一块儿在这儿写了好了QwQ 先港高斯消元趴? 这个算法并不难理解啊?就会矩阵运算就过去了鸭,,, 算了都专门为此写个题解还 ...
随机推荐
- JavaScript:改变 HTML 内容
使用Javascript来处理HTML元素的内容是非常强大的功能. <!DOCTYPE html><html><head><meta http-equiv=& ...
- SpringBoot非官方教程 | 第十九篇: 验证表单信息
转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot19/ 本文出自方志朋的博客 这篇文篇主要简述如何 ...
- linux下重新启动oracle
第一步.以Oracle帐户进入Linux系统 第二步.执行以下命令查看数据库监听器的状况: lsnrctl status 或者查看数据库端口是否被监听(默认1521) netstat -ano | g ...
- c# 本地完整缓存组件
用了一段时间java,java实现服务端程序很简单,有很多公共开源的组件或者软件.但是c#的很少. 现在准备自己写点东西,学习下新的东西,总结下c#的内容以及我们经常用的内容,抽离成类,组件,模型.方 ...
- django-多表操作2
#######多表操作二######## 昨天写了基于双下划线查找,都是两个表之间查找,那再多跨几个表呢?还是一样,一步一步分析 # 跨多表查询: 查询红楼梦这本书的作者的电话: (Author,Bo ...
- 简明 ES6 模块
简明 ES6 模块 1.什么是模块 模块就是一段代码,这段代码可以反复使用,经常单独写成一个文件,一旦加载会立即执行. 2.导出 导出有 2 种方式:命名导出和默认导出,分别用关键字export和ex ...
- Js操作DOM及获取浏览器高度以及宽度
1.获取网页可见区域的宽度:document.body.clientWidth ; 2.获取网页可见区域的高度:document.body.clientHeight; 3.获取 网页可见区域宽:doc ...
- PHP大数组,大文件的处理
[原文来自于转载, 但他的结论不太正确, 尤其对foreach的判断这块上, 我拎过来进行修理 ] 在做数据统计时,难免会遇到大数组,而处理大数据经常会发生内存溢出,这篇文章中,我们聊聊如何处 ...
- mysql 如何监控innodb的阻塞
- Vue插槽 slot
1. 什么是插槽 插槽slot 是往父组件中插入额外内容,实现组件的复用,一个插槽插入到一个对应的标签中 2. 实例: 一个组件中不允许有两个匿名插槽 </head> <body&g ...