emm这个题目说实话,假如没人指点就会很难,比如说我,,,自己看了很久没看懂,我首先读了个假题就去群里问,真tm弱智QAQ.
这题假如你真懂高斯消元就会简单很多.我先带大家回顾下高斯消元..高斯消元是用来解多元一次方程组,然后可能这个方程可以用另外一个方程表示,那么我这个一次方程是不是就没有了意义?然后消完之后假如出现0!=0的方程显然无解hh..
那么这个题也可以用高斯消元的思想来解,怎么解呢?我们这个题基本就变成了一个没有右边项的题目.未知数可以自己加,emm,就这样~
然后讲下方程消元顺序是没关系的.且最多的装备也一定是定值,你可以类比坐标系的确定.然后消元的时候采取贪心的方式进行消元,为什么要这么消呢?因为显然,我选小的消大的,那我存下来的必然是小的,而不是大的hh.而有些等价方程,我消掉大的总比我消掉小的好吧?(请仔细思考高斯消元)
代码如下:
#include <bits/stdc++.h> using namespace std; const double eps=1e-6; const int N=505; int cnt=0,ans=0,n,m; struct vv{ long double v[N]; int w; }a[N]; bool cmp(vv aa,vv bb) { return aa.w<bb.w; } void gauss() { int c,r;//r行c列. for(c=1,r=1;c<=m;c++,r++) { if(fabs(a[r].v[c])<=eps) continue; cnt++;ans+=a[r].w; for(int i=m;i>=c;i--) a[r].v[i]/=a[r].v[c]; for(int i=r+1;i<=n;i++) { for(int j=m;j>=c;j--) { a[i].v[j]-=a[i].v[c]*a[r].v[j]; } } } } int main() { cin>>n>>m; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>a[i].v[j]; } } for(int i=1;i<=n;i++) cin>>a[i].w; sort(a+1,a+1+n,cmp); gauss(); cout<<cnt<<' '<<ans<<endl; return 0; }