NWERC 2013

66 篇文章 0 订阅
17 篇文章 1 订阅

B Battle for Silver

容易发现答案最多有4个点,枚举所有4个点一下的完全图。

#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
#define fr(x) freopen(x,"r",stdin)
#define fw(x) freopen(x,"w",stdout)
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
int S[1000],n,m;
bool b[500][500];
int u[1000],v[1000];
int main()
{
//  freopen("B.in", "r", stdin);
    while(cin>>n>>m) {
        For(i,n) For(j,n) b[i][j]=0;
        int ans=0;
        For(i,n) S[i]=read(), gmax(ans,S[i])
        For(i,m) {
            u[i]=read(),v[i]=read();
            b[u[i]][v[i]]=b[v[i]][u[i]]=1;
            gmax(ans,S[u[i]]+S[v[i]])
        }
        For(i,m) {
            For(j,n) if (u[i]!=j && v[i] != j &&b[u[i]][j] && b[v[i]][j] ){
                gmax(ans,S[j] + S[u[i]] + S[v[i]] )
            }
            For(j,m) if (u[i]!=u[j] && v[i] != u[j] && u[i]!=v[j] && v[i] != v[j] ){
                if (b[u[i]][v[j]] &&b[u[j]][v[i]] && b[u[i]][u[j]]  && b[v[i]][v[j]] ) {
                    gmax(ans,S[u[j]] + S[v[j]] + S[u[i]] + S[v[i]] )

                }
            }
        }
        cout<<ans<<endl;

    }   

    return 0;
}

C Card Trick

概率dp

G Grachten

#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
#define fr(x) freopen(x,"r",stdin)
#define fw(x) freopen(x,"w",stdout)
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
ll gcd(ll a,ll b) {if (!b) return a;return gcd(b,a%b);}
int main()
{
    ll x,y,z;
//  freopen("G.in", "r", stdin);
    while(cin>>x>>y>>z) {
        ll p1=x*z;
        ll p2=z-y;
        ll g=gcd(p1,p2);
        p1/=g,p2/=g;
        p1-=x*p2;
        cout<<p1<<'/'<<p2<<endl;
    }   

    return 0;
}

I Infix to Prefix

显然我们可以区间dp O(n3) 暴力转移
然后这样就可以过了。

#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (100000000000000ll)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
#define fr(x) freopen(x,"r",stdin)
#define fw(x) freopen(x,"w",stdout)
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (1010)
string Filename="I";
int n;
char s[MAXN];
ll dpmax[MAXN][MAXN],dpmin[MAXN][MAXN];
bool vis[MAXN][MAXN],valid[MAXN][MAXN];
bool calc(int i,int j) {
    if (i>j) return 0;
    if (vis[i][j]) return valid[i][j];
    vis[i][j]=1;
    dpmax[i][j]=-INF;
    dpmin[i][j]=INF;

    if (s[i]=='+') {
        Fork(k,i+1,j-1) {
            if (calc(i+1,k) && calc(k+1,j)) {
                gmax(dpmax[i][j] , dpmax[i+1][k] + dpmax[k+1][j] );
                gmin(dpmin[i][j] , dpmin[i+1][k] + dpmin[k+1][j] );
                valid[i][j]=1;
            }
        }
    }
    if (s[i]=='-') {
        if (calc(i+1,j)) {
            gmax(dpmax[i][j] , - dpmin[i+1][j]  );
            gmin(dpmin[i][j] , - dpmax[i+1][j]  );
            valid[i][j]=1;
        }
        Fork(k,i+1,j-1) {
            if (calc(i+1,k) && calc(k+1,j)) {
                gmax(dpmax[i][j] , dpmax[i+1][k] - dpmin[k+1][j] );
                gmin(dpmin[i][j] , dpmin[i+1][k] - dpmax[k+1][j] );
                valid[i][j]=1;
            }
        }
    }
    return valid[i][j];
}
int main()
{
//  freopen((Filename+".in").c_str(), "r", stdin);
    while(scanf("%s",s+1)==1) {
        n=strlen(s+1);
        MEM(vis) MEM(valid)
        For(i,n) if (isdigit(s[i])) {
            ll p=0;
            Fork(j,i,min(i+8,n) ) {
                if (!isdigit(s[j])) break;
                p=p*10+s[j]-'0';
                dpmax[i][j]=dpmin[i][j]=p;
                valid[i][j]=vis[i][j]=1;
                if (j==i && s[i]=='0') break;
            }
        }
        calc(1,n);
        cout<<dpmin[1][n]<<' '<<dpmax[1][n]<<endl;
    } 


    return 0;
}

J Jingle Balls

考虑先把树清空在往里扔苹果,计算放同等数量苹果时和原来的非重合数个数(只考虑完空树中填苹果)
根据限制条件,假设现在某个子树要放k个苹果,容易发现最多只有2种情况。
同时由于每次节点数都会变为原来的一半,最多只要计算 log500 层,就剩0个或1个苹果,可以特判跳出。
答案=往空树里填了几次苹果

#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (1000000)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
#define fr(x) freopen(x,"r",stdin)
#define fw(x) freopen(x,"w",stdout)
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
string Filename="J";
char s[10000];
int tot=0,n;
int pre[10000];
int a[10000];
bool fl=1;
int ans=0;
int f[5310][2310];
int Abs(int x){return max(-x,x);
}
bool dfs(int l,int r,int k) {
    if (!k) {
        f[l][k]=0; return 1;
    }

    ++l,--r;    
    if (l==r) {
        int pson=k;
        if (k==1) {
            f[l-1][k]=0;
            return 1;       
        } else if (k==0) {
            f[l-1][k]=1;
            return 1;       
        }
        return 0;
    }
    else if (r==l-1) {
        int pson=k;
        if (k==0) {
            f[l-1][k]=0;
            return 1;       
        } else if (k==1) {
            f[l-1][k]=1;
            return 1;       
        }
        return 0;
    }

    int pl=pre[l],pr=pre[r];

    f[l-1][k]=INF;
    if (dfs(l,pl,k>>1)&& dfs(pr,r,k-(k>>1) )) {
        gmin(f[l-1][k],f[l][k>>1]+f[pr][k-(k>>1)]);
    }
    int side=k>>1;
    if (side!=k-side)
        if (dfs(l,pl,k-side)&& dfs(pr,r,side) ) {
            gmin(f[l-1][k],f[l][k-side]+f[pr][side]);
        }
    return f[l-1][k]!=INF;

}
stack<int> st;
int main()
{
//  freopen((Filename+".in").c_str(), "r", stdin);
    while(scanf("%s",s+1)!=EOF) {
        n=strlen(s+1); tot=0;
        a[0]=0;
        For(i,n) {
            a[i]=a[i-1]+(s[i]=='B');
            if (s[i]=='B') ++tot;
            else if (s[i]=='(') st.push(i);
            else if (s[i]==')'){
                int p=st.top();st.pop();
                pre[i]=p,pre[p]=i;
            }
        }
        fl=dfs(1,n,tot);
        if (!fl) puts("impossible");
        else {
            printf("%d\n",f[1][tot]);
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值