题意:你是卖票的,一张票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");
}
}
题意:给定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("");
}
}
}
C Mafia
题意:一个游戏,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);
}
}
题意:给一棵有根树,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]);
}
}