这俩都是钱币兑换问题,就是拿着一种货币换成其他货币,通过利率的不同最后再换回来钱是否会增多。这两个题我是用最短路的floyd做的,通过遍历所有点,找过一遍关系,也就是把钱换一遍。
其实这种题也可以用bellman做,因为这种题都是判断
有没有正权回路求最大值(跟那个负权回路求最小值很像)
不同的是bellman的做法是只需要最后看看有没有负权回路,有的话就是可以,没有的话就不可以,而floyd则是相当于先处理好所有的值,最后看看有没有大于原来的值,大于了就是可以,否则反之。
第一个题:
Currency Exchange(poj1860)
大概题意:有很多货币,货币之间可以交换,当然里边利率不同,钱最后也不同,当你用100A币交换B币时,A到B的汇率是29.75,手续费是0.39,那么你可以得到(100 - 0.39) * 29.75 = 2963.3975 B币。问s币的金额经过交换最终得到的s币金额数能否增加。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m,s;
double v;
double map1[105][105],map2[105][105],mapp[105];
int floyd()
{
double d[105];
for(int i=1; i<=n; i++)
d[i]=mapp[i];
for(int k=1; k<=n; k++)
{
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
if((mapp[i]-map2[i][j])*map1[i][j]>mapp[j])
mapp[j]=(mapp[i]-map2[i][j])*map1[i][j];
}
}
}
for(int i=1; i<=n; i++)
if(d[i]<mapp[i])
return 1;
return 0;
}
int main()
{
while(~scanf("%d%d%d%lf",&n,&m,&s,&v))
{
int a,b;
double c,d,e,f;
memset(map1,0,sizeof(map1));
memset(map2,0,sizeof(map2));
memset(mapp,0,sizeof(mapp));
for(int i=1; i<=m; i++)
{
scanf("%d%d%lf%lf%lf%lf",&a,&b,&c,&d,&e,&f);
map1[a][b]=c,map2[a][b]=d;
map1[b][a]=e,map2[b][a]=f;
}
mapp[s]=v;
floyd();
if(floyd())
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
第二题:
Arbitrage(poj2240)
题意:已知n种货币,以及m种货币汇率及方式,问能否通过货币转换,使得财富增加。
跟上道题差不多,就还是floyd找一遍,然后对比
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
char a[35][35];
char a1[35];
double x;
char b[35];
double mapp[35][35];
int main()
{
int n,m,cas=1;
while(~scanf("%d",&n)&&n)
{
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
{
if(i==j)
mapp[i][j]=1;
}
for(int i=1; i<=n; i++)
scanf("%s",a[i]);
scanf("%d",&m);
for(int i=1; i<=m; i++)
{
scanf("%s%lf%s",a1,&x,b);
int j;
for(j=1; j<=n; j++)
if(strcmp(a[j],a1)==0)
break;
int k;
for(k=1; k<=n; k++)
if(strcmp(a[k],b)==0)
break;
mapp[j][k]=x;
}
for(int k=1; k<=n; k++)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
{
if(mapp[i][j]<mapp[i][k]*mapp[k][j])
mapp[i][j]=mapp[i][k]*mapp[k][j];
}
printf("Case %d: ",cas++);
int i;
for(i=1; i<=n; i++)
if(mapp[i][i]>1) break;
if(i>n) printf("No\n");
else printf("Yes\n");
}
}