Codeforces Round #202 (Div. 2)

8 篇文章 0 订阅
1 篇文章 0 订阅



题意:你是卖票的,一张票25,有n人在排队买票,每人只有25,50,100面额中的一种,问能否在不改变队伍顺序的情况下找零,你的初始金额为0。

思路:暴力

/*************************************************************************
     File Name: A.cpp
     ID: obsoles1
     PROG: 
     LANG: C++ 
     Mail: 384099319@qq.com 
     Created Time: 2016年07月14日 星期四 08时57分54秒
 ************************************************************************/
#include<bits/stdc++.h>
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();++it)
#define Abs(x,y) ((x)>(y)?((x)-(y)):((y)-(x)))
#define ll long long
#define Mem0(x) memset(x,0,sizeof(x))
#define Mem1(x) memset(x,-1,sizeof(x))
#define MemX(x) memset(x,0x3f,sizeof(x))
#define pb push_back
using namespace std;

int main(){
  int n,i,x;
  while(~scanf("%d",&n)){
    bool flag=0;
    int cnt25=0,cnt50=0;
    for(i=0;i<n;++i){
      scanf("%d",&x);
      if(x==25)cnt25++;
      if(x==50)cnt25--,cnt50++;
      if(x==100){
        if(cnt50)cnt50--,cnt25--;
        else cnt25-=3;
      }
      if(cnt25<0 || cnt50<0)flag=1;
    }
    if(flag)puts("NO");
    else puts("YES");
  }
}



B Color the Fence


题意:给定n代表油漆数和九个数代表数i所需油漆数,求能画出的最大数字

思路:找出最小值确定数字位数,从前往后每一位都在保证的位数的情况下找最大的数字

/*************************************************************************
     File Name: B.cpp
     ID: obsoles1
     PROG: 
     LANG: C++ 
     Mail: 384099319@qq.com 
     Created Time: 2016年07月14日 星期四 09时13分57秒
 ************************************************************************/
#include<bits/stdc++.h>
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();++it)
#define Abs(x,y) ((x)>(y)?((x)-(y)):((y)-(x)))
#define ll long long
#define Mem0(x) memset(x,0,sizeof(x))
#define Mem1(x) memset(x,-1,sizeof(x))
#define MemX(x) memset(x,0x3f,sizeof(x))
#define pb push_back
using namespace std;
const int INF=0x3f3f3f3f;
int a[20];

int main(){
  int n,i;
  while(~scanf("%d",&n)){
    int mina=INF,pos;
    for(i=1;i<10;++i){
      scanf("%d",a+i);
      if(mina>=a[i])mina=a[i],pos=i;
    }
    if(n<mina)puts("-1");
    else{
      while(n>=mina){
        int cnt=n/mina-1;
        int nn=n-cnt*mina;
        //cout<<"\nnn="<<nn<<endl;
        for(i=1;i<10;++i){
          //cout<<"a["<<i<<"]="<<a[i]<<endl;
          if(a[i]<=nn)pos=i;
        }
        printf("%d",pos);
        n-=a[pos];
      }
      puts("");
    }
  }
}





题意:一个游戏,n个人组成,一个要当主持人,也就是说n-1个人在玩。n个人分别想玩ai轮,问能满足所有人的最少轮数是多少。

思路:设能满足所有人的轮数是x,则(x-a1)+(x-a2)+……(x-an)>=x,即要保证每轮都有主持人。化简式子求出x的最小值即可。

/*************************************************************************
     File Name: C.cpp
     ID: obsoles1
     PROG: 
     LANG: C++ 
     Mail: 384099319@qq.com 
     Created Time: 2016年07月14日 星期四 09时43分14秒
 ************************************************************************/
#include<bits/stdc++.h>
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();++it)
#define Abs(x,y) ((x)>(y)?((x)-(y)):((y)-(x)))
#define ll long long
#define Mem0(x) memset(x,0,sizeof(x))
#define Mem1(x) memset(x,-1,sizeof(x))
#define MemX(x) memset(x,0x3f,sizeof(x))
#define pb push_back
using namespace std;

int main(){
  int n,i;
  ll x;
  while(~scanf("%d",&n)){
    ll sum=0,ans=0;
    for(i=0;i<n;++i){
      scanf("%I64d",&x);
      sum+=x;
      ans=Max(ans,x);
      //cout<<"sum="<<sum<<endl;
    }
    ans=Max(ans,(sum+n-2)/(n-1));
    printf("%I64d\n",ans);
  }
}



D Apple Tree


题意:给一棵有根树,1为根,叶子节点有权重,求要使该树平衡(即每个节点的子节点权重相等)最少需要减去多少权重。

思路:树形dp。要使树平衡,节点权重必须为子节点个数cnt的倍数,它的子节点又分别是不同的数的倍数,要数它的子节点的权重相等,则需求一个最小公倍数m,则节点权重为cnt×m的倍数。

/*************************************************************************
     File Name: D.cpp
     ID: obsoles1
     PROG: 
     LANG: C++ 
     Mail: 384099319@qq.com 
     Created Time: 2016年07月14日 星期四 17时52分01秒
 ************************************************************************/
#include<bits/stdc++.h>
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();++it)
#define Abs(x,y) ((x)>(y)?((x)-(y)):((y)-(x)))
#define ll long long
#define Mem0(x) memset(x,0,sizeof(x))
#define Mem1(x) memset(x,-1,sizeof(x))
#define MemX(x) memset(x,0x3f,sizeof(x))
#define pb push_back
using namespace std;
const int N=1e5+10;
const ll INF=0x3f3f3f3f3f3f3f3f;
ll dp[N],limit[N],cnt[N];
int top;
struct Edge{
  int to;
  Edge *next;
}*head[N],e[N<<1];

void Addedge(int from,int to){
  Edge *p=&e[++top];
  p->to=to,p->next=head[from],head[from]=p;
}

void dfs(int ch,int pre){
  limit[ch]=1;
  cnt[ch]=0;
  for(Edge *p=head[ch];p;p=p->next)
    if(p->to!=pre){
      dfs(p->to,ch);
      ll g=__gcd(limit[ch],limit[p->to]);
      limit[ch]*=limit[p->to];
      limit[ch]/=g;//算的是最小公倍数
      cnt[ch]++;
    }
  if(cnt[ch])limit[ch]*=cnt[ch];
}

void tree_dp(int ch,int pre){
  ll minn=INF,tmp;
  for(Edge *p=head[ch];p;p=p->next){
    if(p->to!=pre){
      tree_dp(p->to,ch);
      minn=Min(minn,dp[p->to]);
      tmp=limit[ch]/cnt[ch];//tmp可能为0!!!
      if(tmp)minn-=minn%tmp;
    }
  }
  if(!dp[ch])dp[ch]=cnt[ch]*minn;
}

int main(){
  int n,i,p1,p2;
  while(~scanf("%d",&n)){
    top=0,Mem0(head);
    ll sum=0;
    for(i=1;i<=n;++i){
      scanf("%I64d",dp+i);
      sum+=dp[i];
    }
    for(i=1;i<n;++i){
      scanf("%d%d",&p1,&p2);
      Addedge(p1,p2);
      Addedge(p2,p1);
    }
    dfs(1,-1);
    tree_dp(1,-1);
    printf("%I64d\n",sum-dp[1]);
  }
}



E Subset Sums




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值