CCPC-Wannafly Winter Camp Day4 (Div2, onsite)

D:

/*
贪心的 构造出来欧拉回路
就是把度为3的点改一改
方法是把4周的边隔一个扔一个
这些扔掉的边一定要走两遍
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#define maxn 1010
using namespace std;
int n,m,ans;
int main(){
    scanf("%d%d",&n,&m);n--;m--;
    if(n==1){
        ans=m*2+m+1+m-1;
        printf("%d\n",ans);return 0;
    }
    if(m==1){
        ans=n*2+n+1+n-1;
        printf("%d\n",ans);return 0;
    }
    ans+=n/2;
    if(n&1)ans+=m/2;
    else ans+=(m+1)/2;
    if((n+m)&1){
        ans+=(n+1)/2;
        if(n&1)ans+=(m+1)/2;
        else ans+=m/2;
    }
    else {
        ans+=n/2;
        if(n&1)ans+=m/2;
        else ans+=(m+1)/2;
    }
    ans+=n*(m+1)+m*(n+1);
    printf("%d\n",ans);
    return 0; 
}

I:

/*
首先,肯定是用来打b的牌最后一块出 
假设我们已经确定了有x张牌用来召唤怪兽
那么对于一张牌 如果他用来打a那价值就是a
如果它用来打b那价值就是b*x
但是ab只能用一个 
所以这种可以互相打破的价值不能用来做排序的key
我们考虑 如果全都打b,那么总价值是固定的
对于一张牌 改成打a 总价值+a-b*x    
然后我们取 这个值前x大的 
*/ 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define maxn 1010
#define ll long long
using namespace std;
ll n,now,sumb,Ans;
struct node{
    ll a,b;
}r[maxn];
ll cmp(const node &A,const node &B){
    return (A.a-A.b*now)>(B.a-B.b*now);
}
int main(){
    scanf("%lld",&n);
    for(ll i=1;i<=n;i++){
        scanf("%lld%lld",&r[i].a,&r[i].b);
        sumb+=r[i].b;
    }
    for(now=1;now<=n;now++){
        sort(r+1,r+1+n,cmp);ll s=0;
        for(ll i=1;i<=now;i++)s+=r[i].a-r[i].b*now;
        Ans=max(Ans,sumb*now+s);
    }
    printf("%lld\n",Ans);
    return 0;
}

I:(div1)

/*
对于div1 的数据 枚举x肯定是gg了
然后就比较骚了
div2的程序枚举x过程中 
我们发下ans是先增后减
大胆猜一发三分 
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define maxn 100010
#define ll long long
using namespace std;
ll n,now,sumb,Ans;
struct node{
    ll a,b;
}r[maxn];
ll cmp(const node &A,const node &B){
    return (A.a-A.b*now)>(B.a-B.b*now);
}
ll Cal(ll x){
    now=x;sort(r+1,r+1+n,cmp);ll s=0;
    for(ll i=1;i<=now;i++)s+=r[i].a-r[i].b*now;
    Ans=max(Ans,sumb*now+s);return sumb*now+s;
}
int main(){
    scanf("%lld",&n);
    for(ll i=1;i<=n;i++){
        scanf("%lld%lld",&r[i].a,&r[i].b);
        sumb+=r[i].b;
    }
    ll l=0,r=n,m1,m2,a1,a2;
    while(l<=r){
        m1=(l+r)/2;m2=(m1+r)/2;
        a1=Cal(m1);a2=Cal(m2);
        if(a1>a2)r=m2-1;
        else l=m1+1;
    }
    printf("%lld\n",Ans);
    return 0;
} 

 

posted @ 2019-03-02 13:37  一入OI深似海  阅读(299)  评论(0编辑  收藏  举报