G68 实数线性基+高斯消元法 P3265 [JLOI2015] 装备购买

视频链接:G68 实数线性基+高斯消元法 P3265 [JLOI2015] 装备购买_哔哩哔哩_bilibili

 

 

P3265 [JLOI2015] 装备购买 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

// 线性基+高斯消元法 O(n*m*m)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const double eps=1e-5;
const int N=510;
int n,m;
struct node{
  double z[N]; //属性
  int c;       //花费
  bool operator<(node& b){
    return c<b.c;
  }
}a[N];
int p[N],cnt,ans;

void gauss(){ //高斯消元法
  for(int i=1;i<=n;++i){
    for(int j=1;j<=m;++j){
      if(abs(a[i].z[j])>eps){ //如果(i,j)>0
        if(!p[j]){ //如果p[j]不存在
          p[j]=i;  //记录最高位为第j位的线性基
          ans+=a[i].c; //累计花费
          cnt++;       //累计个数
          break;
        }
        else{ //如果p[j]存在,则行消元
          double d=a[i].z[j]/a[p[j]].z[j];
          for(int k=j;k<=m;++k)
            a[i].z[k]-=a[p[j]].z[k]*d;
        }
      }
    }
  }
}
int main(){
  cin>>n>>m;
  for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j) cin>>a[i].z[j];
  for(int i=1;i<=n;++i) cin>>a[i].c;
  sort(a+1,a+1+n); //按花费升序
  gauss();
  cout<<cnt<<' '<<ans<<endl;
}

 

// 线性基+贪心法 O(n*m*m)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const double eps=1e-5;
const int N=510;
int n,m;
struct node{
  double z[N]; //属性
  int c;       //花费
  bool operator<(node& b){
    return c<b.c;
  }
}a[N];
int p[N],cnt,ans;

void insert(int i){ //贪心法
  for(int j=1;j<=m;++j){
    if(abs(a[i].z[j])>eps){ //如果(i,j)>0
      if(!p[j]){ //如果p[j]不存在
        p[j]=i;  //记录最高位为第j位的线性基
        ans+=a[i].c; //累计花费
        cnt++;       //累计个数
        break;
      }
      else{ //如果p[j]存在,则行消元
        double d=a[i].z[j]/a[p[j]].z[j];
        for(int k=j;k<=m;++k)
          a[i].z[k]-=a[p[j]].z[k]*d;
      }
    }
  }
}
int main(){
  cin>>n>>m;
  for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j) cin>>a[i].z[j];
  for(int i=1;i<=n;++i) cin>>a[i].c;
  sort(a+1,a+1+n); //按花费升序
  for(int i=1;i<=n;++i) insert(i);
  cout<<cnt<<' '<<ans<<endl;
}

 

posted @ 2024-07-16 16:01  董晓  阅读(79)  评论(0编辑  收藏  举报