• UVA 1614 Hell on the Markets


    https://vjudge.net/problem/UVA-1614

    题目

    金融危机中有的银行倒闭,有的被其他银行收购。危机快结束时,只剩下了两家银行继续运转,虽然市场仍然停业,但是新出台的政策正在鼓励市场逐渐开张。为了避免投机行为,同时为了鼓励市场复苏,只允许人们在一个金融机构中交易,并且第 $i$ 分钟交易量不能超过 $i$ 笔。

    两个银行决定和政府合作刺激市场复苏。银行的董事会已经对第一次交易时段中每分钟的交易量达成一致。其中一个银行会在第 $i$ 分钟买入 $a_i$ 份合约,另外一个银行就卖出 $a_i$ 份合约。他们不关心到底是买入还是卖出,因为旁观者只能看到每分钟的交易量。他们仅仅关心如何降低自己的风险,在这个交易时段结束的时候自己不要有多余的合约。我们定义 $b_i=1$ 为第一个银行在第 $i$ 分钟买入合约, $b_i=-1$ 为第二个银行在第 $i$ 分钟买入合约(此时第一个银行卖出合约),那么要求就是这个交易时段中需要满足 $sumlimits_{i = 1}^n {{a_i}{b_i}}  = 0$。

    你们所在的三人团队非常幸运,挺过了这次金融危机,并且银行对你们团队所在的数据中心开放了数据。你们的任务是找出这样的 $b_i$ ,如果不可能找出就报告。

    题解

    需要证明:对于任意的$1 leqslant x leqslant S_i$ ($S_i$ 为 ${a_i}$ 前 $i$ 项的和),都能从前 $i$ 项中选 $j$ ($1leqslant j leqslant i$)个数,使他们的和为 $x$。

    出自:https://wcr1996.com/2015/02/26/uva-1614-hell-on-the-markets/

    证明需要用第二数学归纳法

    设P(i)为对于任意的$1 leqslant x leqslant S_i$ ($S_i$ 为 ${a_i}$ 前 $i$ 项的和),都能从前 $i$ 项中选 $j$ ($1leqslant j leqslant i$)个数,使他们的和为 $x$。

    P(1)显然成立……

    要使P(i)对任意的i成立,用第二数学归纳法,需假设P(1),P(2),P(3),...,P(k-1)成立,并证明P(k)也成立。

    即对任意的 $xin[1,S_k]$ ,都能选出j个数使和为 $x$。

    因为P(k-1)成立,可以不选第$k$个数,所以只需证明对任意的 $xin[S_{k-1}+1,S_k]$ ,都能选出j个数使和为 $x$。

    设 $1leqslant pleqslant a_k$,使

    [S_{k-1}+p = S_{k}-(a_k-p)]

    成立

    因 $0leqslant a_k-p leqslant k-1$ ,又P(1),P(2),P(3),...,P(k-1)都成立,所以一定存在一种前k-1个数选择使它们的和为 $a_k-p$,只需去掉这些数就可以凑出任意的 $xin[S_{k-1}+1,S_k]$ 。

    接下来就是凑解了……

    一定存在这样的选择,那么我们就凑sum/2……

    显然sum为奇数时凑不出来

    从大到小找出一个小于等于当前和的数后,将和减去这个数可以得到新的和

    之前证明了一定可以凑出新的和,于是可以继续减……

    第一次见到第二数学归纳法,还是记下……

    #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
    #include<bits/stdc++.h>
    using namespace std;
    #define REP(r,x,y) for(register int r=(x); r<(y); r++)
    #define REPE(r,x,y) for(register int r=(x); r<=(y); r++)
    #ifdef sahdsg
    #define DBG(...) printf(__VA_ARGS__)
    #else
    #define DBG(...)
    #endif
    
    #define MAXN 100007
    struct node {
    	int x, id;
    	
    }arr[MAXN];
    inline bool cmp(const node& l, const node& r) {
    	return l.x>r.x;
    }
    bool ans[MAXN];
    int main() {
    	int t;
    	while(~scanf("%d", &t) && t) {
    		long long sum = 0;
    		memset(ans,0,sizeof ans);
    		REP(i,0,t) {
    			scanf("%d", &arr[i].x);
    			arr[i].id=i;
    			sum += arr[i].x;
    		}
    		sort(arr,arr+t,cmp);
    		if(sum&1) {
    			printf("No
    ");
    			continue;
    		}
    		printf("Yes
    ");
    		sum>>=1;
    		REP(i,0,t) {
    			if(arr[i].x<=sum) {
    				sum-=arr[i].x;
    			} else {
    				ans[arr[i].id]=1;
    			}
    		}
    		REP(i,0,t) {
    			if(i) putchar(' ');
    			if(ans[i]) printf("-1");
    			else printf("1");
    		}
    		putchar('
    ');
    	}
    	return 0;
    }
    

    重新拉动经济增长

  • 相关阅读:
    运算符的优先级
    % 取余运算 取模运算
    Java运算符,关系运算符
    自增自减 a++,++a,a--,--a
    Java运算符,算术运算符
    启用div作为编辑器 添加contentEditalbe = “true”,如何让在Html中特殊字符不被转义
    一个合格前端必看的书籍
    JQuery中eq()和get()的区别
    div,contenteditable编辑器之ctrl+enter换行,enter发送
    Angularjs 源码
  • 原文地址:https://www.cnblogs.com/sahdsg/p/10525618.html
Copyright © 2020-2023  润新知