首页 > 代码库 > 【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】白色情人节欢乐赛