测试地址:Happiness
题目大意:有
N
种食品和
做法:这一道题需要使用单纯形法解线性规划。
将每个人得到的第
i
种食品量设为
一种优化方法:使用单纯形法来换基的时候,可以贪心使得每一次转轴变换后目标函数尽可能大,这样时间会得到显著优化。
犯二的地方:理解错题目,以为线性规划的解就是最后的答案,结果还要乘
M
<script type="math/tex" id="MathJax-Element-1595">M</script>……
以下是本人代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define eps 1e-8
#define inf 1e9
using namespace std;
int n,m,p[51];
double matrix[51][51],tmp[51];
void solve()
{
while(1)
{
int k1,k2;
double mx;
memset(tmp,0,sizeof(tmp));
memset(p,0,sizeof(p));
for(int i=1;i<=n;i++)
if (matrix[m+1][i]<0)
{
double Min=inf;
for(int j=1;j<=m;j++)
if (matrix[j][i]>0)
{
double t=matrix[j][n+1]/matrix[j][i];
if (Min>t)
{
Min=t;
p[i]=j;
}
}
if (p[i]) tmp[i]=-matrix[m+1][i]*matrix[p[i]][n+1]/matrix[p[i]][i];
}
mx=0.0;
for(int i=1;i<=n;i++)
if (tmp[i]>mx) mx=tmp[i],k2=i;
if (fabs(mx)<eps) break;
k1=p[k2];
//贪心
matrix[k1][k2]=1.0/matrix[k1][k2];
for(int i=1;i<=n+1;i++)
if (i!=k2) matrix[k1][i]*=matrix[k1][k2];
for(int i=1;i<=m+1;i++)
if (i!=k1)
{
for(int j=1;j<=n+1;j++)
if (j!=k2) matrix[i][j]-=matrix[k1][j]*matrix[i][k2];
}
for(int i=1;i<=m+1;i++)
if (i!=k1) matrix[i][k2]=-matrix[i][k2]*matrix[k1][k2];
//转轴变换
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(matrix,0,sizeof(matrix));
for(int i=1;i<=n;i++)
{
scanf("%lf",&matrix[m+1][i]);
matrix[m+1][i]=-matrix[m+1][i];
}
for(int i=1;i<=m;i++)
for(int j=1;j<=n+1;j++)
scanf("%lf",&matrix[i][j]);
solve();
int ans=(int)(matrix[m+1][n+1]*m);
if (matrix[m+1][n+1]*m>ans) ans++;
printf("Nasa can spend %d taka.\n",ans);
}
return 0;
}