BZOJ 4004 [JLOI 2015] 装备购买 解题报告
哎这个题 WA 了无数遍。。。果然人太弱。。。
首先我们把这些装备按照花费从小到大排序,然后依次考虑是否能买这个装备。
至于这样为什么是对的,好像有一个叫拟阵的东西可以证明,然而我不会。TATQAQ
至于怎么考虑是否能买这个装备呢,我们可以动态更新线性基,具体操作:
- 对当前向量进行高斯消元,注意要从从高位往低位消。
- 如果消元完毕后当前向量变成了 $0$ 向量,那么我们就可以用之前的装备凑出当前装备,否则就不能凑出来。
每次更新线性基需要 $O(m^2)$ 的时间,要更新 $O(n)$ 次。
时间复杂度 $O(nm^2)$,稍微优化一下应该可以过吧。。。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
#define N 500 + 5
#define Mod 998244353 int n, m, tot, ans;
int Ord[N], W[N]; struct Node
{
int num[N];
Node () {memset(num, , sizeof(num));}
inline void init()
{
for (int i = ; i <= m; i ++)
scanf("%d", num + i);
}
inline bool operator < (const Node a) const
{
for (int i = ; i <= m; i ++)
{
if (num[i] != && !a.num[i]) return ;
else if (!num[i] && a.num[i] != ) return ;
}
return ;
}
}A[N], P[N]; inline int power(int u, int v)
{
int res = ;
for (; v; v >>= )
{
if (v & ) res = (LL) res * u % Mod;
u = (LL) u * u % Mod;
}
return res;
} inline bool cmp(int u, int v)
{
return W[u] < W[v];
} inline bool All_zero(int id)
{
for (int i = ; i <= m; i ++)
if (A[id].num[i] != ) return ;
return ;
} inline int Inc(int a, int b)
{
return a + b - (a + b >= Mod ? Mod : );
} inline bool Modify(int id)
{
if (tot == m) return ;
if (!tot)
{
tot ++;
for (int i = ; i <= m; i ++)
P[tot].num[i] = A[id].num[i];
return ;
}
for (int d = ; d <= tot; d ++)
{
int i = ;
for (; i <= m; i ++)
if (P[d].num[i] != ) break ;
if (!A[id].num[i]) continue ;
int mul = (LL) A[id].num[i] * power(P[d].num[i], Mod - ) % Mod;
for (i = ; i <= m; i ++)
A[id].num[i] = Inc(A[id].num[i], Mod - ((LL) P[d].num[i] * mul % Mod));
}
bool ok = ;
for (int i = ; !ok && i <= m; i ++)
if (A[id].num[i] != ) ok = ;
if (!ok) return ;
tot ++;
for (int i = ; i <= m; i ++)
P[tot].num[i] = A[id].num[i];
for (int d = tot; d > ; d --)
{
if (P[d - ] < P[d])
{
for (int i = ; i <= m; i ++)
swap(P[d - ].num[i], P[d].num[i]);
}
else break ;
}
return ;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("4004.in", "r", stdin);
freopen("4004.out", "w", stdout);
#endif scanf("%d%d", &n, &m);
for (int i = ; i <= n; i ++)
A[i].init();
for (int i = ; i <= n; Ord[i] = i ++)
scanf("%d", W + i);
sort(Ord + , Ord + n + , cmp);
for (int i = ; i <= n; i ++)
{
int _i = Ord[i];
if (All_zero(_i)) continue ;
if (Modify(_i)) ans += W[_i];
}
if (!tot) ans = W[Ord[]], tot = ;
printf("%d %d\n", tot, ans); #ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return ;
}
4004_Gromah
BZOJ 4004 [JLOI 2015] 装备购买 解题报告的更多相关文章
- [JLOI 2015]装备购买
Description 脸哥最近在玩一款神奇的游戏,这个游戏里有 n 件装备,每件装备有 m 个属性,用向量zi(aj ,.....,am) 表示 (1 <= i <= n; 1 < ...
- BZOJ 3992 [SDOI 2015] 序列统计 解题报告
这个题最暴力的搞法就是这样的: 设 $Dp[i][j]$ 为前 $i$ 个数乘积为 $j$ 的方案数. 转移的话就不多说了哈... 当前复杂度 $O(nm^2)$ 注意到,$M$ 是个质数,就说明 $ ...
- BZOJ 3993 [SDOI 2015] 星际战争 解题报告
首先我们可以二分答案. 假设当前二分出来的答案是 $Ans$ ,那么我们考虑用网络流检验: 设武器为 $X$,第 $i$ 个武器的攻击力为 $B_i$: 设机器人为 $Y$,第 $i$ 个机器人的装甲 ...
- NOI 2015 滞后赛解题报告
报同步赛的时候出了些意外.于是仅仅能做一做"滞后赛"了2333 DAY1 T1离线+离散化搞,对于相等的部分直接并查集,不等部分查看是否在同一并查集中就可以,code: #incl ...
- 洛谷 P1108 低价购买 解题报告
P1108 低价购买 题目描述 "低价购买"这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:"低价购买:再低价购买&quo ...
- BZOJ 4005 [JLOI 2015] 骗我呢
首先,我们可以得到:每一行的数都是互不相同的,所以每一行都会有且仅有一个在 $[0, m]$ 的数没有出现. 我们可以考虑设 $Dp[i][j]$ 为处理完倒数 $i$ 行,倒数第 $i$ 行缺的数字 ...
- BZOJ 4316: 小C的独立集 解题报告
4316: 小C的独立集 Description 图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨. 这不,小C让小D去求一个无向图的最大独立集,通俗地讲就是:在无向图中选出若干个点, ...
- bzoj 2588 Count on a tree 解题报告
Count on a tree 题目描述 给定一棵\(N\)个节点的树,每个点有一个权值,对于\(M\)个询问\((u,v,k)\),你需要回答\(u\) \(xor\) \(lastans\)和\( ...
- BZOJ 3545 / 洛谷 P4197 Peaks 解题报告
P4197 Peaks 题目描述 在\(\text{Bytemountains}\)有\(N\)座山峰,每座山峰有他的高度\(h_i\).有些山峰之间有双向道路相连,共\(M\)条路径,每条路径有一个 ...
随机推荐
- 使用laravel 的artisan快速创建表
参考:使用laravel 的artisan快速创建表 字段类型参考链接: 结构生成器 版本: Laravel 4.2 1. 创建migrate 文件 php artisan migrate:make ...
- 第四章 jQuery中的事件
1.加载DOM jQuery中,在$(document).ready()方法内注册的事件,只要DOM就绪就会被执行,此时可能元素的关联文件未下载完. jQuery中的 load()方法,会在元素的on ...
- c# json转Dictionary字典
JavaScriptSerializer s = new JavaScriptSerializer(); string jsonTexts = "{\"count\" ...
- C#学习笔记15:字符串、文件、目录的操作方法
字符串:不可变性 String str=”abcdf”; 将字符串转换为char数组:ToCharArray(); Char[] ch=str.ToCharAarray(); 将char数组转换为字符 ...
- 利用openssl进行RSA加密解密
openssl是一个功能强大的工具包,它集成了众多密码算法及实用工具.我们即可以利用它提供的命令台工具生成密钥.证书来加密解密文件,也可以在利用其提供的API接口在代码中对传输信息进行加密. RSA是 ...
- iOS 的一点理解(一) 代理delegate
做了一年的iOS,想记录自己对知识点的一点理解. 第一篇,想记录一下iOS中delegate(委托,也有人称作代理)的理解吧. 故名思议,delegate就是代理的含义, 一件事情自己不方便做,然后交 ...
- 关于char 指针变量char *=p;这个语句的输出问题
学习指针的时候我一直有个疑惑,请看下面的代码: #include <iostream> using std::cout; void main() { ; int *nPtr=&nu ...
- C语言变参函数/Variadic fucntion
几个重要的 宏/类型 定义 Macros Defined in header <stdarg.h> va_start enables access to variadic function ...
- MFC下拉框使用方法
Combo Box (组合框)控件很简单,可以节省空间.从用户角度来看,这个控件是由一个文本输入控件和一个下拉菜单组成的.用户可以从一个预先定义的列表里选择一个选项,同时也可以直接在文本框里面输入文本 ...
- 一个css3流程导图
这也是公司用到的,写个demo出来分享 <!DOCTYPE html> <html> <head> <meta http-equiv="Conten ...