procedure2012
It's not worth it to know you're not worth it!

[关键字]:数学 解方程组

[题目大意]:给出一种目标饲料的比例,和三种其他饲料的比例,问用这三种饲料各多少能混合出目标饲料多少,要求总用量最小。

//=============================================================================================================================================

[分析]:其实一点都不难,以样例为例。目标为3:4:5,其余三种为1:2:3 3:7:1 2:1:2,设第一种用x,第二种用y,第三种用z,得到k目标。可得方程组:

1x+3y+2z=3k

2x+7y+1z=4k

3x+1y+2z=5k

然后枚举k,并用高斯消元法判断是否有合法解(非负整数),如果有说明找到了答案否则继续枚举,直到结束都没有,就认为没有解。至于枚举量200就够了。

[代码]:

View Code
/*
ID:procedure2
PROB:ratios
LANG:C++
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

int a[10][10],b[10][10],t1,t2,t3,ans;
double m[10];

double Calc()
{
for (int i=1;i<3;i++)
{
int t=i+1;
while (!b[i][i]&&t<=3)
for (int j=1;j<=4;j++) swap(b[i][j],b[t][j]);
for (int j=i+1;j<=3;j++)
if (b[j][i])
for (int k=4;k>=1;k--)
b[j][k]=b[j][k]*b[i][i]-b[i][k]*b[j][i];
}
for (int i=3;i>=1;i--)
{
double sum=b[i][4];
for (int j=i+1;j<=3;j++) sum-=b[i][j]*m[j];
m[i]=sum/b[i][i];
}
for (int i=1;i<=3;i++)
if (m[i]!=(double)(int)m[i] || m[i]<0) return 0;
return 1;
}

int main()
{
//freopen("ratios.in","r",stdin);
//freopen("ratios.out","w",stdout);
scanf("%d%d%d",&t1,&t2,&t3);
scanf("%d%d%d",&a[1][1],&a[2][1],&a[3][1]);
scanf("%d%d%d",&a[1][2],&a[2][2],&a[3][2]);
scanf("%d%d%d",&a[1][3],&a[2][3],&a[3][3]);
/*for (int i=1;i<=3;i++)
for (int j=1;j<=4;j++) printf("%d %d %d\n",i,j,a[i][j]);
*/
for (int i=1;i<=10000;i++)
{
a[1][4]=t1*i,a[2][4]=t2*i,a[3][4]=t3*i;
memcpy(b,a,sizeof(a));
ans=i;
/*if (i==98)
for (int i=1;i<=3;i++)
for (int j=1;j<=4;j++) printf("%d %d %d\n",i,j,b[i][j]);
*/
if (Calc()) break;
}
if (ans<10000) printf("%d %d %d %d\n",(int)m[1],(int)m[2],(int)m[3],ans); else printf("NONE");
//if (m[1]>0 && m[2]>0 && m[3]>0) printf("%.0lf %.0lf %.0lf %d\n",m[1],m[2],m[3],ans); else printf("NONE");
//system("pause");
return 0;
}



posted on 2012-02-25 18:33  procedure2012  阅读(395)  评论(0编辑  收藏  举报