• yzoj P2344 斯卡布罗集市 题解


    共t条街对于每一条街上有n个店铺(n可能不相同),每次只能选两端第一个营业的店铺采购,采购第i个店铺会获得幸福度ai,采购完后,这个店铺和它相邻的店铺便会关门,问最大幸福度?

    考场想了一下dp,一开始想一维但发现不好处理,二维参数也没有想出来,于是便开始了我的暴力瞎搞之旅,我随手写了几个例子发现对于n为奇数无论怎么采购,幸福度是固定的为a1, a3 , a5........an于是便可以直接累加,然而对于n为偶数又怎么去处理呢?我也随手写了n为6,8,10的数据发现其实就只有三种情况。

    第一种情况:选编号为奇数的

    第二种情况:选编号为偶数的

    第三种情况:选两头,再考虑中间,举个栗子

    3 8 20 8 15 12 12 25 
    

    对于这组数据我们选完a1 a8后再去进行选择a3 a5我们把选了用o表示没选的用x表示就是

    o x o x o x x

    貌似一定又两个连在一起的不选,但考场我也没去证明就直接用了,枚举这两个不选的位置就行,跑完样例发现过了便直接提交了,结果a了,自己也很懵逼。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    int t,n;
    long long f[310][1510],ans,tmp1,tmp2;
    int main(){
        t=read();
        for(int i=1;i<=t;++i){
            n=read();
            for(int j=1;j<=n;++j){
                f[i][j]=read();
            }
            if(n&1){
                for(int j=1;j<=n;++j){
                    if(j&1) ans+=f[i][j];
                }
            }
            else{
                tmp2=0; 
                for(int j=0;j<=n;++j){
                    tmp1=0;
                    for(int k=1;k<j;k+=2){
                        tmp1+=f[i][k];
                    }
                    for(int k=j+2;k<=n;k+=2){
                        tmp1+=f[i][k];
                    }
                    tmp2=max(tmp1,tmp2);
                }
                ans+=tmp2;
            }
        }
        printf("%lld",ans);
        return 0;
    }
    

    貌似可以hack掉,可能数据比较水就a了,再放一个大佬写的前缀和表达

    #include<algorithm>
    #include<cstdio>
    #define ll long long
    #define MX 10001
    using namespace std;
    inline int read(){
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    int T,n;
    ll ans=0;
    int a[MX];
    ll suml[MX],sumr[MX];
    int main(){
    	T=read(); 
    	while(T--){
    		n=read();
    		sumr[n+1]=0;
    		for(int i=1;i<=n;++i){
    			a[i]=read();
    			if(i&1){
    				suml[i]=suml[i-1]+a[i];
    			}else{
    				suml[i]=suml[i-1];
    			}
    		}
    		if(n&1){
    			ans+=suml[n];
    		}else{
    			for(int i=n;i>=1;--i){
    				if(i&1){
    					sumr[i]=sumr[i+1];
    				}else{
    					sumr[i]=sumr[i+1]+a[i];
    				}
    			}
    			ll sum=0;
    			for(int i=1;i<=n;++i){
    				sum=max(sum,suml[i-1]+sumr[i+1]);
    			}
    			ans+=sum;
    		}
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    hdu2438 三分
    hdu3786 找出直系亲属 水题
    hdu3786 找出直系亲属 水题
    hdu4561 连续最大积
    hdu4561 连续最大积
    hdu4604 不错的子序列问题
    hdu4604 不错的子序列问题
    hdu4450 不错的贪心
    hdu1722 切蛋糕
    hdu3768 spfa+全排列
  • 原文地址:https://www.cnblogs.com/donkey2603089141/p/11416467.html
Copyright © 2020-2023  润新知