bzoj 4004 [JLOI2015]装备购买——拟阵证明贪心+线性基
Posted narh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 4004 [JLOI2015]装备购买——拟阵证明贪心+线性基相关的知识,希望对你有一定的参考价值。
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4004
看Zinn博客水过去……
运用拟阵可以证明按价格从小到大买的贪心是正确的。但自己还不会。
然后如果当前物品可以被线性表出就不买了。否则买,在第一个不能线性表出的位置上记录这个物品,表示按已经被消成这样的这个物品的这一位来消掉这一位是可以和前面那些位的消的情况吻合的。
然后因为卡精度而用long double。在printf里是Lf。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define ld long double using namespace std; const int N=505;const ld eps=1e-8; int n,m,ans,cnt,p[N]; bool vis[N]; struct Node{ ld a[N];int w; }t[N]; bool cmp(Node u,Node v){return u.w<v.w;} int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%Lf",&t[i].a[j]); for(int i=1;i<=n;i++)scanf("%d",&t[i].w); sort(t+1,t+n+1,cmp); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(fabs(t[i].a[j])<eps)continue; if(!vis[j]) { vis[j]=1;p[j]=i; ans+=t[i].w;cnt++;break; } else { ld tmp=t[i].a[j]/t[p[j]].a[j]; for(int k=j;k<=m;k++) t[i].a[k]-=t[p[j]].a[k]*tmp; } } printf("%d %d ",cnt,ans); return 0; }
以上是关于bzoj 4004 [JLOI2015]装备购买——拟阵证明贪心+线性基的主要内容,如果未能解决你的问题,请参考以下文章