首页 > 代码库 > 【20170311】白色情人节欢乐赛
【20170311】白色情人节欢乐赛
我出的水题,因为是白色情人节前一天,所以题目背景。。
试题:/s/1pKKkCeJ vyh3 (百度云)
T1:chocolate
题意:给你n个妹子,每个妹子对你的初始好感度为c0[i],你不给她x块巧克力她的好感度会下降c1点,你给她y块巧克力她的好感度会上升c2点,现在问你,你有m块巧克力的情况下你可以获得的好感度之和最大是多少。
解题思路:显然是个01背包类型的DP。时间效率O(nm).
标程:
#include<cstdio> #include<iostream> #include<cstring> #include<string> #include<algorithm> #include<cmath> #define For(i,a,b) for (int i=a; i<=b; i++) #define Ford(i,a,b) for (int i=a; i>=b; i--) #define File(fn) freopen(fn".in","r",stdin); freopen(fn".out","w",stdout); #define mem(qaq,num) memset(qaq,num,sizeof(qaq)); #define ll long long #define mod 1000000007 #define INF 2000000000 using namespace std; int c1[5001],c2[5001],f[45001],w1[5001],w2[5001],n,m,sum; inline int in(){ int x=0,f=1; char ch=getchar(); while (ch<‘0‘||ch>‘9‘) f=ch==‘-‘?-1:1,ch=getchar(); while (ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*f; } void init(){ n=in(),m=in(); For(i,1,n) sum+=in(),w1[i]=in(),c1[i]=in(),sum-=c1[i],w2[i]=in(),c2[i]=in()+c1[i]; For(i,0,m) f[i]=sum; } void dp(){ For(i,1,n){ Ford(j,m,w1[i]) f[j]=max(f[j-w1[i]]+c1[i],f[j]); Ford(j,m,w2[i]) f[j]=max(f[j-w2[i]]+c2[i],f[j]); } } int main(){ init(); dp(); printf("%d",f[m]); }
T2:date
题意简析:题目其实就是给你个森林,问你能否在合法情况下走到叶节点,如果可以输出当时女神好感度最大的路径,否则输出在任意一点结束时的女神最大好感度以及路径。
解题思路:用个虚根将森林转成树,然后按题意遍历模拟一遍即可。时间效率O(n).
标程:
#include<cstdio> #include<iostream> #include<cstring> #include<string> #include<algorithm> #include<cmath> #define For(i,a,b) for (int i=a; i<=b; i++) #define Ford(i,a,b) for (int i=a; i>=b; i--) #define File(fn) freopen(fn".in","r",stdin); freopen(fn".out","w",stdout); #define mem(qaq,num) memset(qaq,num,sizeof(qaq)); #define ll long long #define mod 1000000007 #define INF 2000000000 using namespace std; struct zxy{ int fa,lson,rbra,val,t,t2; }tr[200001]; int n,e,ans=0,np=0; ll f[200001],m,q; inline ll in(){ ll x=0,f=1; char ch=getchar(); while (ch<‘0‘||ch>‘9‘) f=ch==‘-‘?-1:1,ch=getchar(); while (ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*f; } inline void doit(int k,ll t){ if (tr[k].rbra) doit(tr[k].rbra,t); if (f[tr[k].fa]-tr[k].t2<q&&tr[k].fa) return; if (t+tr[k].t2>m) return; f[k]=f[tr[k].fa]+tr[k].val-tr[k].t2; if (f[k]<q&&k) return; if (f[k]>f[np]) np=k; if (!tr[k].lson){ if (f[k]>f[ans]){ ans=k; } return; } doit(tr[k].lson,t+tr[k].t+tr[k].t2); return; } inline void print(int k){ if (k==0) return; print(tr[k].fa); printf("%d ",k); } int main(){ n=in(),m=in(),q=in(); e=in(); For(i,1,e){ int x=in(),y=in(),t=in(); tr[y].fa=x; tr[y].rbra=tr[x].lson; tr[x].lson=y; tr[y].t2=t; } For(i,1,n) tr[i].t=in(); For(i,1,n) tr[i].val+=in(); For(i,1,n) if(!tr[i].fa){ tr[i].rbra=tr[0].lson; tr[0].lson=i; } doit(0,0); if (!ans){ printf("There are no possibilities that zxyer can spend the whole night with zxy.\n"); printf("%I64d\n",f[np]); print(np); } else{ printf("Zxyer can spend the whole night with zxy succeesfully.\n%I64d\n",f[ans]); print(ans); } return 0; }
T3:light
题意简析:给你张图叫你求最小割。
解题思路:毫无建图难度对不对?最小割=最大流,跑一遍最大流不就行了?
标程:
#include<cstdio> #include<iostream> #include<cstring> #include<string> #include<algorithm> #include<cmath> #define For(i,a,b) for (int i=a; i<=b; i++) #define Ford(i,a,b) for (int i=a; i>=b; i--) #define File(fn) freopen(fn".in","r",stdin); freopen(fn".out","w",stdout); #define mem(qaq,num) memset(qaq,num,sizeof(qaq)); #define ll long long #define mod 1000000007 #define INF 2000000000 using namespace std; struct zxy{ int next,to,v; }edge[100010]; int n,cnt=1,e,p,head[2001],lev[2001],que[2001]; inline int in(){ int x=0,f=1; char ch=getchar(); while (ch<‘0‘||ch>‘9‘) f=ch==‘-‘?-1:1,ch=getchar(); while (ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*f; } inline void ins(int x,int y,int l){ edge[++cnt].to=y,edge[cnt].next=head[x],edge[cnt].v=l,head[x]=cnt; edge[++cnt].to=x,edge[cnt].next=head[y],edge[cnt].v=0,head[y]=cnt; } inline bool bfs(int s,int tt){ mem(lev,-1); int t=1,h=0; que[0]=s; lev[s]=0; do{ h++; int k=head[que[h]]; while(k){ if (lev[edge[k].to]==-1&&edge[k].v){ lev[edge[k].to]=lev[que[h]]+1; que[++t]=edge[k].to; } k=edge[k].next; } }while(h<t); return lev[tt]!=-1; } inline int dfs(int u,int v,int f){ if (u==v) return f; int used=0,k=head[u]; while(k){ if (edge[k].v&&lev[edge[k].to]==lev[u]+1){ int w=dfs(edge[k].to,v,min(edge[k].v,f-used)); used+=w; edge[k].v-=w; edge[k^1].v+=w; if (used==f) return used; } k=edge[k].next; } if(!used) lev[u]=-1; return used; } int dinic(int s,int t){ int flow=0; while(bfs(s,t)){ flow+=dfs(s,t,INF); } return flow; } void init(){ n=in(),e=in(),p=in(); For(i,1,e){ int x=in(),y=in(),l=in(); ins(x,y,l); } } void solve(){ int ans=dinic(0,n+1); if (p<ans) printf("-1"); else printf("%d",ans); } int main(){ init(); solve(); }
【20170311】白色情人节欢乐赛
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。