• 【五校联考7day1】游戏


    此题共三种解法(也许吧)

    排序+贪心=切掉

    上标:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    struct node{int x,y;}b[100010];
    int n,now=0,ans=0;
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    int cmp(node x,node y) {return x.x>y.x;}
    
    int main()
    {
    	freopen("game.in","r",stdin);
    	freopen("game.out","w",stdout);
    	n=read();
    	for (int i=1;i<=n;i++) b[i]=(node){read(),i};
    	sort(b+1,b+n+1,cmp);
    	for (int i=1;i<=n;i++)
    		if (now<b[i].y) ans+=(b[i].y-now)*b[i].x,now=b[i].y;
    	printf("%d
    ",ans);
    	return 0;
    }
    

    上面那个还要排序,有点慢,再来个不排序的。

    在这里插入图片描述
    我们发现了点东东:
    在这里插入图片描述
    就是这样子的如果遇见了比a[las]的大的,就说明有也仅有las~i这一区间属于las的。
    上标:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,las,ans=0,a[100010];
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    int main()
    {
    	freopen("game.in","r",stdin);
    	freopen("game.out","w",stdout);
    	las=n=read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	for (int i=n-1;i>0;i--)
    		if (a[i]>a[las]) ans+=(las-i)*a[las],las=i;
    	printf("%d
    ",ans+las*a[las]);
    	return 0;
    }
    

    斜率优化!一个很骚的解法。

    我们来搞一个样例:
    4
    1 50 1 50
    我们画个图,发现:
    哈哈
    我们发现什么呢?
    我们发现红线是相对于黑线是较优的,应为这是凸包!
    而题目所求的为最大值,所以直线最先触碰到的一定是红线的两端(而非中间的那个点)
    而这样子,我们发现如果点再多一点的话会成这样:
    呵呵
    发现它的斜率越来越小了, 这样子就满足了单调性!
    我们就记录那些点,然后每次对于i就二分求出其直线最先碰到的点即可,那里转移到i就是最有的了。
    然后再加入i点之前,先把前面不符合的点去掉,再添加。
    上标:

    #include<cstdio>
    #include<algorithm>
    #define N 100010
    #define db double
    using namespace std;
    int n,a[N],f[N],g[N],len=0,l,r,mid,s;
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    db solve(int x,int y) {return (db)(f[x]-f[y])/(x-y);}
    
    int main()
    {
    	freopen("game.in","r",stdin);
    	freopen("game.out","w",stdout);
    	n=read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	for (int i=1;i<=n;i++)
    	{
    		l=1,r=len,s=0;
    		while (l<=r)
    		{
    			mid=l+r>>1;
    			if (solve(g[mid],g[mid-1])>=a[i]) s=mid,l=mid+1;
    			else r=mid-1;
    		}
    		f[i]=f[g[s]]+a[i]*(i-g[s]);
    		while (solve(g[len],g[len-1])<solve(i,g[len]) && len) len--;
    		g[++len]=i;
    	}
    	printf("%d
    ",f[n]);
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    [POJ2456]Aggressive cows(贪心,二分查找)
    [POJ1064]Cable master
    [Hadoop]单机尝试安装并测试Hadoop2.7.1(附带注释脚本)
    [HDOJ5500]Reorder the Books
    [UVA11076]Add Again
    [BNU弱校联萌]背水一战
    [HDOJ4911]Inversion
    POJ2735/Gym 100650E Reliable Nets dfs
    Gym 100650H Two Ends DFS+记忆化搜索
    HDU 4292 Food 最大流
  • 原文地址:https://www.cnblogs.com/jz929/p/11817603.html
Copyright © 2020-2023  润新知