HDU-1422 重温世界杯 ACM解题报告(贪心)

这题就是给出生活费和花费,相减后得到一个序列,从某一位开始往后累加,每次sum都必须大于等于0,求最长的这样的子序列,并且这题达到n后可以再从1开始,是一个环,而且参观的城市数不能大于n。

这题的问题就是那个环,我一开始也是二啊,就是在输入的时候处理,这样可以求出1-n中这样的最长的子序列,但是不能求越过n后再从1开始的,后来我想了些办法算这个序列,但是一直WA,也找不到什么测试数据,所以只好看题解,感觉自己真的是不行啊。把1-(n-1)的序列再补在n后面,就是一个2n-1的序列,然后就在这个序列里求最长子序列,如果长度等于n就跳出。

这个贪心的证明也是显而易见的,如果此时的sum大于0,而且如果你此时这个数在最长子序列中,但是你当前的序列不为最长子序列,这是显然不成立的啊,因为你现在不加当前这个数,sum是大于等于0,而这个数所在的序列必定和前面的序列相邻,所以这个方法得到的就是最优解。

#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<stack>
using namespace std;
#define MAX 105
typedef long long LL;
const double pi=3.141592653589793;
const int INF=1e9;
const double inf=1e20;
int c[100005];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int a,b;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&a,&b);
            c[i]=a-b;
        }
        int sum=0,cnt=0,maxn=0;
        for(int i=0;i<2*n-1;i++)
        {
            sum+=c[i%n+1];
            if(sum>=0)
            {
                cnt++;
                if(cnt>maxn) maxn=cnt;
                if(cnt==n) break;
            }
            else
            {
                sum=0;
                cnt=0;
            }
        }
        printf("%d\n",maxn);
    }
    return 0;
}

你可能感兴趣的:(ACM)