card card card HDU - 6205(尺取思想)

card card card HDU - 6205

As a fan of Doudizhu, WYJ likes collecting playing cards very much.
One day, MJF takes a stack of cards and talks to him: let’s play a game and if you win, you can get all these cards. MJF randomly assigns these cards into n heaps, arranges in a row, and sets a value on each heap, which is called “penalty value”.
Before the game starts, WYJ can move the foremost heap to the end any times.
After that, WYJ takes the heap of cards one by one, each time he needs to move all cards of the current heap to his hands and face them up, then he turns over some cards and the number of cards he turned is equal to the penaltyvalue.
If at one moment, the number of cards he holds which are face-up is less than the penaltyvalue
, then the game ends. And WYJ can get all the cards in his hands (both face-up and face-down).
Your task is to help WYJ maximize the number of cards he can get in the end.So he needs to decide how many heaps that he should move to the end before the game starts. Can you help him find the answer?
MJF also guarantees that the sum of all “penalty value” is exactly equal to the number of all cards.
Input
There are about 10 test cases ending up with EOF.
For each test case:
the first line is an integer n (1≤n≤106), denoting n heaps of cards;
next line contains n integers, the ith integer ai (0≤ai≤1000) denoting there are ai cards in ith heap;
then the third line also contains n integers, the ith integer bi (1≤bi≤1000) denoting the “penalty value” of ith heap is bi
.
Output
For each test case, print only an integer, denoting the number of piles WYJ needs to move before the game starts. If there are multiple solutions, print the smallest one.
Sample Input

5
4 6 2 8 4
1 5 7 9 2

Sample Output

4

Hint

[pre]
For the sample input:

+ If WYJ doesn't move the cards pile, when the game starts the state of cards is:
    4 6 2 8 4
    1 5 7 9 2
WYJ can take the first three piles of cards, and during the process, the number of face-up cards is 4-1+6-5+2-7. Then he can't pay the the "penalty value" of the third pile, the game ends. WYJ will get 12 cards.
+ If WYJ move the first four piles of cards to the end, when the game starts the state of cards is:
    4 4 6 2 8
    2 1 5 7 9
WYJ can take all the five piles of cards, and during the process, the number of face-up cards is 4-2+4-1+6-5+2-7+8-9. Then he takes all cards, the game ends. WYJ will get 24 cards.

It can be improved that the answer is 4.

**huge input, please use fastIO.**
[/pre]

题意:

第一行一个数n代表n堆卡片
第二行n个数,代表每堆多少张卡片 a i
第三行n个数,代表每堆的价值 b i
在开始前,可以把第一堆挪到最后去,并且可以这样操作任意次,也就是相当于可以让n个数循环移动
游戏开始后,从第一堆开始拿,把第一堆全拿过来,把新拿来的卡片全部朝上,然后每堆代表的价值是几,就把几张卡片翻转(朝上变朝下),当某次拿过来一堆卡片并完成操作后,朝上的卡片数小于这一堆的价值,游戏结束,此时手里已经有了若干卡片。
问要是游戏结束后手里卡片最多,游戏开始前,至少挪动几次

分析:

可以将n对卡片存两遍,当成2n的数组,表示循环

发现只需计算 a i b i 的前缀和,并满足大于等于零,长度不超过n即可

可以用尺取思想,移动区间,每次移动减去前面的一个,加上后面新的一个,没到不符合条件时,比较更新牌数最大值

code:

#include <bits/stdc++.h>
using namespace std;
int n;
int val[2000010];
int sum[2000010];
int main(){
    while(~scanf("%d",&n)){
        memset(sum,0,sizeof(sum));
        for(int i = 1; i <= n; i++){
            scanf("%d",&val[i]);
            val[i+n] = val[i];
        }
        for(int i = 1; i <= 2 * n; i++){
            sum[i] = sum[i-1] + val[i];
        } //卡片数前缀和
        for(int i = 1; i <= n; i++){
            int b;
            scanf("%d",&b);
            val[i] -= b;
            val[i+n] -= b;
        }
        int r = 0;
        int ans = 0;//答案即换的次数
        int maxc = 0;//记录最大卡片数
        int tmp = 0;//前缀和,保证大于等于0才继续
        for(int i = 1; i <= n; i++){//i代表左,r代表右
            r++;
            while(r - i < n && r <= 2 * n && tmp >= 0){
                tmp += val[r];
                r++;
            }
            r--;
            int s = sum[r] - sum[i-1];
            if(s > maxc){
                maxc = s;
                ans = i - 1;
            }
            tmp -= val[i];
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/codeswarrior/article/details/81393122