bzoj 4004 装备购买

比较裸的拟阵的题,按照价值从小到大排一个序,高斯消元就行了。
这道题太变态了,我eps开1e-8就wa了,开1e-5就a了

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>

#define md
#define ll long long
#define inf (int) 1e9
#define eps 1e-5
#define N 510
using namespace std;
struct data { int id,w;} b[N];
double a[N][N];
int vis[N];
bool cmp(data a,data b) { return a.w<b.w; }
void outit()
{
for (int i=1;i<=3;i++)
{
for (int j=1;j<=3;j++)
printf("%.2lf ",a[i][j]);
printf("\n");
}
printf("\n");
}
int main()
{
int n,m; ll ans=0; int tot=0;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
scanf("%lf",&a[i][j]);
for (int i=1;i<=n;i++) { scanf("%d",&b[i].w); b[i].id=i;}
sort(b+1,b+n+1,cmp);
for (int i=1;i<=n;i++)
{
int x=b[i].id;
for (int j=1;j<=m;j++)
if (fabs(a[x][j])>eps)
{
if (vis[j])
{
double p=a[x][j]/a[vis[j]][j];
for (int k=1;k<=m;k++) a[x][k]-=p*a[vis[j]][k];
}
else
{
vis[j]=x; break;
}
}
for (int j=1;j<=m;j++)
if (fabs(a[x][j])>eps) { ans+=b[i].w; tot++; break; }
//outit();
}
printf("%d %lld\n",tot,ans);
return 0;
}


你可能感兴趣的:(bzoj 4004 装备购买)