P2199 [JZOJ/中山市市选] 股票投资

很多人都梦想成为股神,但是股票投资是需要一定基本功的。熟知股票买卖的规则就是其中一件很重要的事情。顾名思义,股票的单位是“股”;但是实际上,在公开交易市场,股票交易的单位是“手”,\(1\) 手股票等于 \(100\) 股股票。另外,和其他商业买卖一样,股票交易是要纳税的。股票交易的税有两种,一种是交易税,一种是印花税。假设当前股价是\(P\),你要买或者卖 \(X\) 手股票,那么你需要付出或者得到的钱是 \(G=P \times X \times 100\)。与此同时,无论买或者买,你都必须支付交易税和印花税。印花税有一个固定税率 \(T\),例如 \(0.001\),则你所需支付的印花税为 \(G \times T\)。交易税类似印花税,也有一个固定税率S1,但同时也有一个最低税额 \(S_2\),这意味着,如果 \(G*S_1<S_2\),则你依然需要支付 \(S_2\) 的税款,即你需要缴纳的税款为 \(\max(G \times S1,S2)\)
好了,懂得这个规则,现在你可以小试牛刀了。不过,股票市场更需要的是投资策略。问题来了,假设某个时刻 \(T_0\),你拥有 \(C\) 元现金;接下来的 \(n\) 秒钟,\(T_1\),\(T_2\),…,\(T_n\),你都清楚知道某一只股票的价格 \(P_i\)。在这 \(n\) 秒钟,你都可以任意买入或者卖出或者持有这只股票,当然,无论什么时候,你必须保证你的现金不能出现负数,你也不可能卖出比你持有数量更多的股票。同时 \(T\),\(S_1\),\(S_2\)也是已知的。在这样的情况下,第 \(n\) 秒结束后,你可以拥有的现金最多会是多少?

  • \(f_i\) 为没有股票时,最多剩余的钱
  • \(c_i\) 为有股票时,最多有多少股票
  • \(h_i\) 为有最多股票的情况下,最多剩余多少钱
  • \(G\) 为买或卖的总价钱
  • \(S\) 为在 \(G\) 的情况下最多的税
  • \(T\) 为印花税的比值
  • \(S_1\) 为交易税的比值
  • \(S_2\) 为交易税的定值总价
  • \(P\) 为今天买或卖的价钱

\(\texttt{原博客链接}\)

Uses math;

Const
	total=30010;

var
	f,c,h:array[-1..total] of extended;
	T,P,S,G,S1,S2:extended;
	test:longint;

procedure Work;
var i,n,l,r,mid:longint;
begin
	fillchar(f,sizeof(f),0);
	fillchar(c,sizeof(c),0);
	fillchar(h,sizeof(h),0);
    read(f[0],S1,S2,T,n); h[0]:=f[0]; 
	for i:=1 to n do
	begin
		read(P); l:=0; r:=maxlongint div n;
		while (l<=r) do
		begin
			mid:=(l+r) >> 1;
			G:=P*100*mid; S:=G*T+max(S2,G*S1);
			if (S+G<=f[i-1]) then begin l:=mid+1; c[i]:=mid; h[i]:=f[i-1]-S-G; end
			else r:=mid-1;
		end;
		if (c[i-1]>c[i])or((c[i-1]=c[i])and(h[i-1]>h[i])) then begin c[i]:=c[i-1]; h[i]:=h[i-1]; end;
		G:=P*100*c[i-1]; S:=G*T+max(S2,G*S1);
		f[i]:=max(f[i-1],h[i-1]+G-S);
	end;
	writeln(f[n]:0:3);
end;

begin
	assign(input,'stock.in');reset(input);
    assign(output,'stock.out');rewrite(output);
	read(test);
	while test>0 do begin Work; dec(test); end;
	close(input); close(output);
end.
posted @ 2019-04-16 13:09  _ARFA  阅读(112)  评论(0编辑  收藏  举报