换钱问题:
给出n种钱,m个站点,现在有第 s种钱,身上有v 这么多;
下面 m行 站点有a,b两种钱,rab a->b的汇率,cab a-->b的手续费, 相反rba cba ; 
问在10次之内,能不能把钱换的变的多了?
Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange operations only with these currencies. There can be several points specializing in the same pair of currencies. Each point has its own exchange rates, exchange rate of A to B is the quantity of B you get for 1A. Also each exchange point has some commission, the sum you have to pay for your exchange operation. Commission is always collected in source currency. 
For example, if you want to exchange 100 US Dollars into Russian Rubles at the exchange point, where the exchange rate is 29.75, and the commission is 0.39 you will get (100 - 0.39) * 29.75 = 2963.3975RUR. 
You surely know that there are N different currencies you can deal with in our city. Let us assign unique integer number from 1 to N to each currency. Then each exchange point can be described with 6 numbers: integer A and B - numbers of currencies it exchanges, and real RAB, CAB, RBA and CBA - exchange rates and commissions when exchanging A to B and B to A respectively. 
Nick has some money in currency S and wonders if he can somehow, after some exchange operations, increase his capital. Of course, he wants to have his money in currency S in the end. Help him to answer this difficult question. Nick must always have non-negative sum of money while making his operations. 

Input

The first line of the input contains four numbers: N - the number of currencies, M - the number of exchange points, S - the number of currency Nick has and V - the quantity of currency units he has. The following M lines contain 6 numbers each - the description of the corresponding exchange point - in specified above order. Numbers are separated by one or more spaces. 1<=S<=N<=100, 1<=M<=100, V is real number, 0<=V<=103
For each point exchange rates and commissions are real, given with at most two digits after the decimal point, 10-2<=rate<=102, 0<=commission<=102
Let us call some sequence of the exchange operations simple if no exchange point is used more than once in this sequence. You may assume that ratio of the numeric values of the sums at the end and at the beginning of any simple sequence of the exchange operations will be less than 104

Output

If Nick can increase his wealth, output YES, in other case output NO to the output file.

Sample Input

3 2 1 20.0
1 2 1.00 1.00 1.00 1.00
2 3 1.10 1.00 1.10 1.00

Sample Output

YES

方法1:用Bellman算法,若存在正权回路,则说明货币经转化是越来越大的,即满足题意。

     所以,这道题就是在让你求回路中是否存在正权回路。

#include "stdio.h"
#include "string.h"
#include "algorithm"
using namespace std;
int n,m,x,flag,u[220],v[220];
double y,dis[220],r1[220],c1[220],r2[220],c2[220];
void djk()
{
for(int i=1;i<n;i++)
{
int ans=0;
for(int j=1;j<=m;j++)
{
if(dis[v[j]]<(dis[u[j]]-c1[j])*r1[j])
{
dis[v[j]]=(dis[u[j]]-c1[j])*r1[j];
ans++;
}
if(dis[u[j]]<(dis[v[j]]-c2[j])*r2[j])
{
dis[u[j]]=(dis[v[j]]-c2[j])*r2[j];
ans++;
}
}
if(ans==0) break;
}
flag=0;
for(int j=1;j<=m;j++)
{
if(dis[v[j]]<(dis[u[j]]-c1[j])*r1[j])
{
flag=1;
break;
}
if(dis[u[j]]<(dis[v[j]]-c2[j])*r2[j])
{
flag=1;
break;
}
}
}
int main()
{
while(~scanf("%d%d%d%lf",&n,&m,&x,&y))
{
memset(dis,0,sizeof(dis));
dis[x]=y;
for(int i=1;i<=m;i++)
scanf("%d%d%lf%lf%lf%lf",&u[i],&v[i],&r1[i],&c1[i],&r2[i],&c2[i]);
djk();
if(flag) printf("YES\n");
else printf("NO\n");
}
}

方法2:

  SPFA方法:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
#define INF 0x3f3f3f
using namespace std;
typedef pair<int,int> P;
const int maxn = 1e2+10;
int n,m,s,tot;
double v;
double dis[maxn];
int head[maxn],vis[maxn];
double cost[maxn][maxn],rate[maxn][maxn];
struct node
{
int to;
double w;
int next;
} edge[maxn*maxn]; void add(int u,int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
} bool SPFA(int s,double v)
{
for(int i=1; i<=n; i++)
{
dis[i] = 0;
vis[i] = 0;
}
dis[s] = v;
vis[s] = 1;
queue<int> q;
q.push(s);
while(!q.empty())
{
int x = q.front();
q.pop();
vis[x] = 0;
for(int i=head[x]; i!=-1; i=edge[i].next)
{
int j = edge[i].to;
if(dis[j]<(dis[x]-cost[x][j])*rate[x][j])
{
dis[j] = (dis[x]-cost[x][j])*rate[x][j];
if(dis[s]>v)
return true;
if(!vis[j])
{
q.push(j);
vis[j] = 1;
}
}
}
}
return false;
} int main()
{
while(cin>>n>>m>>s>>v)
{
int i;
memset(cost,0,sizeof(cost));
memset(rate,0,sizeof(rate));
memset(head,-1,sizeof(head));
tot = 1;
for(i=0; i<m; i++)
{
int a,b;
double cab,rab,cba,rba;
scanf("%d%d%lf%lf%lf%lf",&a,&b,&rab,&cab,&rba,&cba);
cost[a][b] = cab;
cost[b][a] = cba;
rate[a][b] = rab;
rate[b][a] = rba;
add(a,b);
add(b,a);
}
if(SPFA(s,v))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}

C - C(换钱问题)的更多相关文章

  1. 算法进阶面试题07——求子数组的最大异或和(前缀树)、换钱的方法数(递归改dp最全套路解说)、纸牌博弈、机器人行走问题

    主要讲第五课的内容前缀树应用和第六课内容暴力递归改动态规划的最全步骤 第一题 给定一个数组,求子数组的最大异或和. 一个数组的异或和为,数组中所有的数异或起来的结果. 简单的前缀树应用 暴力方法: 先 ...

  2. [DP]换钱的方法数

    题目三 给定数组arr, arr中所有的值都为整数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,在给定一个整数aim代表要找的钱数,求换钱有多少种方法. 解法一 --暴力递归 用0 ...

  3. OptimalSolution(1)--递归和动态规划(2)矩阵的最小路径和与换钱的最少货币数问题

    一.矩阵的最小路径和 1 3 5 9 1 4 9 18 1 4 9 18 8 1 3 4 9 9 5 8 12 5 0 6 1 14 14 5 11 12 8 8 4 0 22 22 13 15 12 ...

  4. [程序员代码面试指南]递归和动态规划-换钱的方法数(DP,完全背包)

    题目描述 给定arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim,求组成aim的方法数. 解题思路 完全背包 和"求换钱的 ...

  5. 算法之Python实现 - 003 : 换钱的方法数

    [题目]给定数组arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim代表要找的钱数,求组成aim的方法数. [代码1]递归 impor ...

  6. 算法之Python实现 - 002 : 换钱的最少货币数补充(每种货币只能使用一次)

    [题目]:给定数组arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币仅可以使用一张,再给定一个整数aim代表要找的钱数,求组成aim的最少货币数. [代码1]:时间与额 ...

  7. 算法之Python实现 - 001 : 换钱的最少货币数

    [题目]给定数组arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim代表要找的钱数,求组成aim的最少货币数. [代码1]:时间与额外 ...

  8. MT【227】换钱的总数

    (2012复旦)将1张面值100元的人民币全部换成面值1角,2角,5角的人民币,不同的换法有多少种? 解:即求不等式$2x+5y\le1000$的所有非负整数解的个数.由匹克公式:$S=a+\dfra ...

  9. [DP]换钱的最小货币数

    题目一 给定数组arr,数组中有N个元素,其中所有的之都为整数且不重复.每个只代表一种面值的货币,每种面值的货币可以使用任意张,在给定一个整数aim代表要找的钱数,求组成aim的最少货币数. 解法 依 ...

随机推荐

  1. 使用 Flux,Helm v3,Linkerd 和 Flagger 渐进式交付 Kubernetes

    介绍 本指南将引导您在 Kubernetes 集群上设置渐进式交付 GitOps 管道. GitOps Helm 研讨会 原文地址:GitOps Progressive Deliver with Fl ...

  2. 【Git】命令行操作

    Git 命令行操作 1 本地库初始化 git init:初始化本地仓库 效果 注意:.git目录中存放的是本地库相关的子目录和文件,不要删除,也不要胡乱修改. 2 设置签名 形式: 用户名:tom E ...

  3. Loadrunner与kylinPET的能力对比测试--web动态请求

    概述 在<性能测试工具选择策略--仿真度对比测评分析报告>一文详细分析了使用相同的web页面,分别使用LoadRunner,Jmeter,kylinTOP工具进行录制脚本并执行得出在静态请 ...

  4. LeetCode108.有序数组转二叉搜索树

    题目 1 class Solution { 2 public: 3 TreeNode* sortedArrayToBST(vector<int>& nums) { 4 if(num ...

  5. ctfhub技能树—web前置技能—http协议—Cookie

    打开靶机环境 查看显示内容 根据提示,需要admin登录才能得到flag 题目介绍为Cookie欺骗.认证.伪造 介绍一下cookie和session 一.cookie: 在网站中,http请求是无状 ...

  6. win10打开IIS服务并发布网站

    1.打开控制面板 win+x后点击控制面板 2.点击程序集下边的解除安装程式 3.点击开启或关闭windows功能 4.找到Internet information services并勾选前面的复选框 ...

  7. 让 Mongoose 不再重复链接数据库(如何正确连接以解决升级后的报错)

    升级了 Mongoose 后,发现项目打不开了.报错: MongooseError: You can not `mongoose.connect()` multiple times while con ...

  8. 定制个性化的GUI

    你现在还在使用SAP GUI710或者是GUI720,又或者更早的640等吗?那么古董先生,推荐您使用GUI730吧,您可能会730好在哪?那我建议您去百度或者Google问吧.对于新的GUI730, ...

  9. docker 运行时常见错误

    docker 运行时常见错误 (1) Cannot connect to the Docker daemon at unix:///var/run/docker.sock. [root@localho ...

  10. 聊聊.net应用程序的Docker镜像

    ​要在容器中运行.net应用程序,你需要在容器镜像中安装.net Framework或.net Core 运行时.这不是你需要自己管理的东西,因为微软提供的Docker镜像已经安装了运行时,你可以使用 ...