CF - 高精度 + 贪心

Last year Bob earned by selling memory sticks. During each of n days of his work one of the two following events took place:

  • A customer came to Bob and asked to sell him a 2x MB memory stick. If Bob had such a stick, he sold it and got 2x berllars.
  • Bob won some programming competition and got a 2x MB memory stick as a prize. Bob could choose whether to present this memory stick to one of his friends, or keep it.

Bob never kept more than one memory stick, as he feared to mix up their capacities, and deceive a customer unintentionally. It is also known that for each memory stick capacity there was at most one customer, who wanted to buy that memory stick. Now, knowing all the customers‘ demands and all the prizes won at programming competitions during the last n days, Bob wants to know, how much money he could have earned, if he had acted optimally.

Input

The first input line contains number n (1?≤?n?≤?5000) — amount of Bob‘s working days. The following n lines contain the description of the days. Line sell x stands for a day when a customer came to Bob to buy a 2x MB memory stick (0?≤?x?≤?2000). It‘s guaranteed that for each x there is not more than one line sell x. Line win x stands for a day when Bob won a 2x MB memory stick (0?≤?x?≤?2000).

Output

Output the maximum possible earnings for Bob in berllars, that he would have had if he had known all the events beforehand. Don‘t forget, please, that Bob can‘t keep more than one memory stick at a time.

Example

Input

7win 10win 5win 3sell 5sell 3win 10sell 10

Output

1056

Input

3win 5sell 6sell 4

Output

0

题目分析 : 一个人卖内存条,sell 表示有人去买此内存条, win表示获取到此内存条,这个人最多只能拥有一个内存条,并且同时也保证买不同型号内存条的只会有一个顾客,问此人能获得的最大收益。思路分析 : 输出答案得是高精度,选购物品的时候贪心的去选, 因为 2^5 一定大于 2^1 + 2^2 + 2^3 + 2^4。代码示例 :
#define ll long long
const int maxn = 1e6+5;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;

int n;
struct node
{
    int state, x; // 1 是 win, 0 是 sell
    int pt; // 1 是存在
}pre[5005];
vector<int>f[2005];
int p[2005];
vector<int>ans, mid;

void init() {
    f[0].push_back(1);

    for(int i = 1; i <= 2000; i++){
        f[i].assign(f[i-1].size(), 0);
        for(int j = 0; j < f[i].size(); j++){
            f[i][j] = f[i-1][j] + f[i-1][j];
        }
        for(int j = f[i].size()-1; j >= 0; j--){
            if (f[i][j] > 9){
                f[i][j] -= 10;
                if (j != 0) f[i][j-1]++;
                else f[i].insert(f[i].begin(), 1);
            }
        }
    }
}

void bigsum(int x){
    mid.clear();
    mid.assign(ans.size(), 0);

    for(int i = ans.size()-1, j = f[x].size()-1; i >= 0; ){
        if (j >= 0){
            mid[i] = ans[i] + f[x][j];
            i--, j--;
        }
        else {mid[i] = ans[i]; i--;}
    }

    for(int i = mid.size()-1; i >= 0; i--){
        if (mid[i] > 9){
            mid[i] -= 10;
            if (i != 0) mid[i-1]++;
            else mid.insert(mid.begin(), 1);
        }
    }
    ans = mid;
}

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    cin >> n;
    char s[10];
    int x;

    init();
    for(int i = 1; i <= n; i++) {
        scanf("%s%d", s, &x);
        if (s[0] == ‘w‘) pre[i].state = 1;
        else {
             pre[i].state = 0;
             p[x] = i;
        }
        pre[i].x = x; pre[i].pt = 1;
    }

    int sign = 1;
    for(int i = 2000; i >= 0; i--){
        if (!p[i]) continue;
        int pos = 999999;
        for(int j = p[i]-1; j >= 1; j--){
            if (pre[j].pt == 0) break;
            if (pre[j].state == 1 && pre[j].x == i){
                pos = j;
                if (sign) {ans = f[i]; sign = 0;}
                else bigsum(i);
                break;

            }
        }
        for(int j = p[i]; j >= pos; j--){
            if (pre[j].state == 0) p[pre[j].x] = 0;
            else pre[j].pt = 0;
        }
        //printf("-----  %d %d\n", i, pos);
    }
    if (sign) {printf("0\n"); return 0;}
    for(int i = 0; i < ans.size(); i++){
        printf("%d", ans[i]);
    }
    printf("\n");
    //puts("");
    return 0;
}
 

原文地址:https://www.cnblogs.com/ccut-ry/p/8451443.html

时间: 2024-10-10 09:59:44

CF - 高精度 + 贪心的相关文章

CF18D 高精度+贪心

http://codeforces.com/problemset/problem/18/D Last year Bob earned by selling memory sticks. During each of n days of his work one of the two following events took place: A customer came to Bob and asked to sell him a 2x MB memory stick. If Bob had s

洛谷P1080 国王游戏 高精度 贪心 数学推公式

洛谷P1080 国王游戏        数学推公式      高精度    贪心 然而这并不是我打出来的,抄题解... 将左手与右手的乘积从小到大排序,然后计算求最大值即可.(需要高精度) 证明: 1)知道,如果相邻的两个人交换位置,只会影响到这两个人的值,不会影响他人 2)假设相邻的两个人i, i + 1.设A[i] B[i] <= A[i + 1] B[i + 1],i之前所有人的左手乘积为S. 则,ans1 = max{S / B[i], S * A[i] / B[i + 1]} 若交换

CF 680D 贪心+构造.

题意:若当前体积为X,则每次选一个最接近X的三次方数(p^3<=X)填入. 确定不超过m的X,使得操作次数最多?若有最大操作次数有多种方案,输出X最大的那一种. m<=1e15. x确定ans也就确定 m很大 直接确定x是不可能的.令最大的a满足,a^3<=m. 则第一个塞的长度最大为a,最多剩下m-a^3如果塞边长a-1的 则体积最大剩下a^3-1-(a-1)^3 保证一开始的体积<a^3.塞a-2的 则最大剩下 (a-1)^3-1-(a-2)^3 此时同样塞了一个,第二个可以选

【NOIP2012提高组】国王游戏 贪心 + 高精度

题目分析 题目答案不具有单调性,所以不可以二分,转而思考贪心.因为无法确定位置,所以考虑如何才能让对于每一个$1 ~ i$使得$i$的答案最大,即$1 ~ i$最后一个最优.若设对于位置$i$,$a[i]$表示左手,$b[i]$表示右手,$S$为其前面所有人的左手之积,那么他的答案就是$\frac{S}{b[i]}$,如果存在在$i$后边的$j$的答案更优, 即$\frac{S * a[i]}{b[j]} > \frac{S * a[j]}{b[i]} => a[i] * b[i] >

CF #374 (Div. 2) D. 贪心,优先队列或set

1.CF #374 (Div. 2)   D. Maxim and Array 2.总结:按绝对值最小贪心下去即可 3.题意:对n个数进行+x或-x的k次操作,要使操作之后的n个数乘积最小. (1)优先队列 #include<bits/stdc++.h> #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,sizeof(

POJ 2325 Persistent Numbers#贪心+高精度除法

(- ̄▽ ̄)-* 这道题涉及高精度除法,模板如下: char s[1005]; char division[1005];//存储进行高精度除法的数据 bool bignum_div(int x) { int tot=0,num=0; for(int i=0;s[i];i++) { num=num*10+s[i]-'0'; division[tot++]=num/x+'0'; num%=x; } division[tot]='\0';//利于进行strcpy() if(num==0) //有适合的

CF 332 C 贪心

题目链接:http://codeforces.com/problemset/problem/332/C 参考  链接: http://blog.csdn.net/cc_again/article/details/9471465 题目意思: 有n个命令,要通过p个,某主席要在通过的p个中选择k个接受. 每个任务有两个值ai,bi, ai表示如果该主席接受该命令,她的头发变灰的数量,bi表示如果该主席不接受该命令时,议员不高兴值. 对于通过的p个命令,该主席要使议员的不高兴值和最小,在相同的情况下,

CF(437C)The Child and Toy(贪心)

题意:给出一个无向图,每个点有点权,操作是一个一个将所有点揪走直至剩下一个点,揪走一个点的代价是剩下点中与其连边的点的点权和.求完成操作所需花费的最小代价. 解法:贪心的思想,每次将剩余点中点权最大的点揪出,这样可以保证每条边都是会选择相对小的点权被消耗掉.所以直接输出所有边的边权和即可. 代码: /****************************************************** * author:xiefubao **************************

[贪心][高精度][NOIP]国王游戏

题目梗概 有n个大臣,他们可以拿到他们之前所有人左手数的乘积除以他的右手,问是否能通过调换位置来使拿钱最多的大臣拿的钱最少. 思考 贪心证明: 设相邻的两个人$i, i + 1$.设$A[i] \times B[i] \leqslant  A[i + 1] B[i + 1]$,i之前所有人的左手乘积为S. 则,$ans1 = max \left (\frac{S}{B[i]} , \frac{S}{A[i] \times B[i+1]}  \right )$ 若交换 $ans2 = max \l