Arbitrage题解

START


emmmm,做法和其他几个题解应该差不多,但是我觉得解释可以再多一点。

那么废话不多说。


这道题的要求比较简单,只是要求最后转换成原来的那种货币时获利大于0.01(1%),而且转换次数不超过n次(越少越好),然后输出最短次数的路径。

注意!!!!!:题目并没有要求是最大获利,只要求获利大于0.01。并且对路径也没有具体要求,只是最短并不超过n次,路径长度相同的情况下任何一条都是可以的。

那么!我们就抓住一个比较重要的点——转换次数。

也就是说,每转换一次,我们就将其转换成原来的货币,判断获利是否达到0.01,如果达到了,那么输出之后整个程序就结束了。(如果有多种货币超过0.01,输出其中一种即可)

所以,我们就先在外层一个for循环,循环转换次数,不可超过n。 (如果超过n就输出"no arbitrage sequence exists"好惹)。

并且!!!我们需要保存好每次转换的货币种类,最后要输出的鸭!!!

那么!大概框架出现,我们就需要写核心liao,没错,这道题的核心就是Floyd算法辣。

我们常用的Floyd一般是开一个二维数组,但其实它是三维压缩而来,所以这道题我们用三维数组ans[i][j][k],i表示第i种货币,j表示第j种货币,k表示第k次转换,整体表示从第i种货币转换成第j种货币中第k次转换时的获利。(可能有点绕8)

另外用nxt[i][j][k]表示从第i种货币转换成第j种货币中第k次转换时的货币种类。

那么!转换式就出来liao(虽然不知道为什么)!ans[i][l][k]=max(ans[i][l][k],ans[i][j][k-1]*ans[j][l][1])

它的意思就是说在前一次转化后,现在想从i转换到j,试图通过k,看能不能让值更大,能的话就变大(变大一定不吃亏,因为题目也没要求货币变成多少,只是要求要大于0.01,所以当前要是能变大的话那当然变大,可能有点贪心的意思???)

具体i j k l是啥就进程序康康8


Code:

 1 #include<bits/stdc++.h>
 2 #define MAXN 5001
 3 using namespace std;
 4 __int128 n,r,g,t,b,Ans;//懒于打高精hhhh 
 5 __int128 ans[MAXN][MAXN];//二维ans[i][j]来表示前i个塔有j个干扰塔,则有i-j个放射塔,n-i个激光塔 
 6 int read();
 7 void print(__int128 x){
 8     if(x>9)  print(x/10);
 9     putchar(x%10+'0');//int128是直接输出不了der,所以要这个亚子输出 
10 }
11 int main(){
12     //freopen("antbuster.in","r",stdin);
13     //freopen("antbuster.out","w",stdout);
14     n=read(),r=read(),g=read(),b=read(),t=read();//快读 
15     for(int i=1;i<=n;i++)
16         ans[i][0]=(i-1)*g*t+ans[i-1][0];//初始化,若n个点上全部都放上放射塔 
17     for(int i=1;i<=n;i++)
18         for(int j=1;j<i;j++)
19             ans[i][j]=max(ans[i-1][j-1]+(i-j)*g*(t+(j-1)*b),ans[i-1][j]+(i-j-1)*g*(t+j*b));
20         //共i个点,放j个干扰塔的情况 
21     for(int i=0;i<=n;i++)
22         for(int j=0;j<=i;j++)
23             Ans=max(ans[i][j]+r*(n-i)*(t+j*b)+(i-j)*g*(n-i)*(t+j*b),Ans);
24         //n个点上,i个塔已经放置,剩下n-i个塔全部放置激光塔 
25     print(Ans);//输出 
26     return 0;
27 }
28 int read()//快读 
29 {
30     int x=0,k=1;char ch=' ';
31     while(!isdigit(ch)){
32         ch=getchar();
33         if(ch=='-')  k=-1;
34     }
35     while(isdigit(ch)){
36         x=x*10+ch-'0';
37         ch=getchar();
38     }
39     return k*x;
40 }

END

猜你喜欢

转载自www.cnblogs.com/Yz-jw/p/11480666.html