zoukankan      html  css  js  c++  java
  • EZ 2018 05 26 NOIP2018 模拟赛(十六)

    这次难道就是传说中的标准分大赛?而且这次比赛的链接不翼而飞

    一堆人153pts然后就有Rank4?看来这个Rank4不值钱了,才涨了50+的Rating。

    不过还好最后5min的时候想出了T1正解,否则就会因为少10pts被爆踩了吧

    好了开始讲题。

    T1

    这其实是题,我们很容易想到DP:

    (f_{i,j})表示前(i)个数中有i个数选择正数时的最小价值和,则有转移:

    (f_{i,j}=min(f_{i-1,j-1}+min(a_{i,0},a_{i,1}),f_{i-1,j}-max(a_{i,0},a_{i,1})))

    其中(a_{i,0},a_{i,1})表示这张纸牌正反面的数字

    这里贪心的技巧还是很好想到的,如果是正数的纸牌就让小的一个数露出,负数的纸牌就让大的一个数露出

    然后滚动优化一下即可得到90pts

    但是正解其实要简单很多,这也是很好YY的

    然后我们现在先假设没有负数这一条件,所以我们总是选择每一对(min(a_{i,0},a_{i,1}))来朝上。

    但是由于我们有放在负数位置的权利,所以我们可以让一些数变成(-max(a_{i,0},a_{i,1}))朝上

    然后我们看一下对于从(min(a_{i,0},a_{i,1}))变到(-max(a_{i,0},a_{i,1}))d的时候,相当于把值减少了:

    (min(a_{i,0},a_{i,1})-(-max(a_{i,0},a_{i,1}))=min(a_{i,0},a_{i,1})+max(a_{i,0},a_{i,1})=a_{i,0},a_{i,1})

    所以我们对于所有的数按照(a_{i,0},a_{i,1})从大到小排序,然后前面的一些数就放在负数位置了

    然后就轻松切掉了

    CODE

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=100005;
    struct data
    {
    	int x,y;
    }a[N];
    int n,ans;
    inline char tc(void)
    {
    	static char fl[100000],*A=fl,*B=fl;
    	return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
    }
    inline void read(int &x)
    {
    	x=0; char ch=tc(); int flag=1;
    	while (ch<'0'||ch>'9') { if (ch=='-') flag=-1; ch=tc(); }
    	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc(); x*=flag;
    }
    inline int min(int a,int b)
    {
    	return a<b?a:b;
    }
    inline int max(int a,int b)
    {
    	return a>b?a:b;
    }
    inline bool comp(data a,data b)
    {
    	return a.x+a.y>b.x+b.y;
    }
    int main()
    {
    	//freopen("A.in","r",stdin); freopen("A_.out","w",stdout);
    	register int i; read(n);
    	for (i=1;i<=n;++i)
    	read(a[i].x),read(a[i].y);
    	sort(a+1,a+n+1,comp);
    	for (i=1;i<=n>>1;++i)
    	ans-=max(a[i].x,a[i].y);
    	for (i=(n>>1)+1;i<=n;++i)
    	ans+=min(a[i].x,a[i].y);
    	printf("%d",ans);
    	return 0;
    }
    
    

    T2

    这道题还是比较难搞的。

    刚开始考虑悬线法,发现没什么用就直接上了DP。

    (f_{i,j})表示以(a_{i,j})为右下角的正方形的边长为多少,然后我们要求的就是:

    (sum_{i=1}^nsum_{j=1}^m f_{i,j}(if there is not a furniture on a_{i,j}))

    然后我们可以预处理(l_{i,j},h_{i,j})分别表示(a_{i,j})的左边和上面分别最多有多少个格子没有家具

    然后则有(f_{i,j}=min(f_{i-1,j-1}+1,min(l_{i,j},h_{i,j})))

    特别的如果(a_{i,j})上是家具,那么(f_{i,j}=-1)。这个主要是为了抵消对DP方程的影响,使(f_{I+1,j+1}=0)

    然后(O(n^2))转移即可

    然后优化的话就是在(b)个点之间转移一下但是我真的不会啊

    53ptsCODE

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=1005;
    int a[N][N],l[N][N],h[N][N],f[N][N],n,m,b,x,y;
    long long ans;
    inline char tc(void)
    {
    	static char fl[100000],*A=fl,*B=fl;
    	return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
    }
    inline void read(int &x)
    {
    	x=0; char ch=tc();
    	while (ch<'0'||ch>'9') ch=tc();
    	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
    }
    inline int min(int a,int b)
    {
    	return a<b?a:b;
    }
    int main()
    {
    	//freopen("B.in","r",stdin); freopen("B.out","w",stdout);
    	register int i,j;
    	read(n); read(m); read(b);
    	for (i=1;i<=b;++i)
    	read(x),read(y),a[x][y]=1;
    	for (i=1;i<=n;++i)
    	for (j=1;j<=m;++j)
    	{
    		if (i^1) h[i][j]=a[i-1][j]?0:h[i-1][j]+1;
    		if (j^1) l[i][j]=a[i][j-1]?0:l[i][j-1]+1;
    	}
    	for (i=1;i<=n;++i)
    	for (j=1;j<=m;++j)
    	if (!a[i][j]) 
    	{
    		f[i][j]=min(f[i-1][j-1]+1,min(l[i][j],h[i][j])); 
    		ans+=f[i][j];
    	} else f[i][j]=-1;
    	printf("%lld",ans);
    	return 0;
    }
    
    

    T3

    这道题超级不可做,全场无人写出,集体爆零

    大概是一道平面几何+树形DP的题目,也是很不可做的

    而且这道题,莫名奇妙地没有开放

    然后又是留坑了

  • 相关阅读:
    WebClient与WebRequest差异
    自定义控件的构建(4)
    自定义控件的构建(6)
    Sliverlight中PagedCollectionView的总结
    自定义控件的构建(13)
    自定义控件的构建(8)
    Silverlight中的主题设置
    自定义控件的构建(12)
    自定义控件的构建(7)
    谈谈学完Asp.net 中的自定义控件后的感受
  • 原文地址:https://www.cnblogs.com/cjjsb/p/9147107.html
Copyright © 2011-2022 走看看