USACO 2.3

USACO 2.3.1 

题解:

DP,DP[i]表示长度为i的前缀是否能够分解。

代码:

/*
ID:m1599491
PROG:prefix
LANG:C++
*/
#include<ciostream>
#include<cstdio>
#include<cstring>
#define INF 10000000
#define MAX_N 205
#define MAX_L 200005
 
using namespace std;
 
int n=0;
int ans=0;
bool dp[MAX_L];
string s;
string p[MAX_N];
 
void read()
{
    while(cin>>p[n])
    {
        if(p[n]==".") break;
        n++;
    }
    string temp;
    while(cin>>temp)
    {
        s+=temp;
    }
}
 
void solve()
{
    memset(dp,false,sizeof(dp));
    dp[0]=true;
    for(int i=0,t=s.size();i<t;i++)
    {
        if(dp[i])
        {
            for(int j=0;j<n;j++)
            {
                bool flag=true;
                for(int k=0;k<p[j].size();k++)
                {
                    if(s[k+i]!=p[j][k])
                    {
                        flag=false;
                        break;
                    }
                }
                if(flag) dp[i+p[j].size()]=true;
            }
        }
    }
    for(int i=0;i<=s.size();i++) if(dp[i]) ans=i;
}
 
void print()
{
    cout<<ans<<endl;
}
 
int main()
{
    freopen("prefix.in","r",stdin);
    freopen("prefix.out","w",stdout);
    read();
    solve();
    print();
}
Longint Prefix

 

USACO 2.3.2

题解:

DP,f[i][j]表示i个点构成深度为j的二叉树的方案数。

不难得出,构成满足条件的二叉树的方案数=左子树的方案数*右子树的方案数。

所以,要满足二叉树的深度为j,左子树和右子树两个之间必定至少有一棵树的深度为j-1。

因此可以分三种情况讨论:1、左子树深度=j-1,右子树深度≤j-2;2、左子树深度≤j-2,右子树深度=j-1;3、左右子树深度均为j-1。

因此要新建一个数组t[i][j]表示所有由i个点组成,深度≤j的树的个数。

代码:

/*
ID:m1599491
LANG:C++
TASK:nocows
*/
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#define Mod 9901
#define MaxN 200
#define MaxK 100
using namespace std;

int n,k,i,j,kk;
int f[MaxN][MaxK]={0},t[MaxN][MaxK]={0};

main()
{
    freopen("nocows.in", "r", stdin);
    freopen("nocows.out", "w", stdout);
    scanf("%d%d",&n,&k);
    f[1][1]=1;
    for (i=1; i<=n; i+=2)
    {
        for (j=2; j<=k; j++)
        {
            for (kk=1; kk<=i-2; kk+=2)
            {
                f[i][j]=(f[i][j]+f[kk][j-1]*f[i-1-kk][j-1])%Mod;
                f[i][j]=(f[i][j]+t[kk][j-2]*f[i-1-kk][j-1])%Mod;
                f[i][j]=(f[i][j]+f[kk][j-1]*t[i-1-kk][j-2])%Mod;
            }
            t[i][j-1]=(f[i][j-1]+t[i][j-2])%Mod;
        }
    }
    printf("%d\n",f[n][k]);
}
Cow Pedigrees

 

USACO 2.3.3

题解:

先算一波N个由0..2构成的元素的全排列,构成一个就check一下,符合就输出。(在全排列那里改一下顺序,输出前就不用排序了233

代码:

/*
ID:m1599491
PROG:zerosum
LANG:C++
*/
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;

int n,i;
int a[10],c[10];

void check()
{
    int sum=a[1],x=0,cc=1;
    for (i=1; i<n; i++)
    {
        if (c[i]==2) sum=sum*10+a[i+1];
        if (c[i]==1 || c[i]==0) 
        {
            if (cc==1) x+=sum; else if (cc==0) x-=sum;
            cc=c[i];
            sum=a[i+1];
        }
    }
    if (cc==0) x-=sum; else if (cc==1) x+=sum;
    if (x!=0) return;
    for (i=1; i<=n; i++)
    {
        if (i==n) {printf("%d\n",a[i]);break;}
        if (c[i]==1) printf("%d+",a[i]);
        if (c[i]==0) printf("%d-",a[i]);
        if (c[i]==2) printf("%d ",a[i]);
    }
}

void dfs(int dep)
{
    int i,j;
    if (dep==n) {check();return;}
    c[dep]=2;dfs(dep+1);
    c[dep]=1;dfs(dep+1);
    c[dep]=0;dfs(dep+1);
}

main()
{
    freopen("zerosum.in","r",stdin);
    freopen("zerosum.out","w",stdout);
    scanf("%d",&n);
    for (i=1; i<=n; i++) a[i]=i;
    dfs(1);
    return 0;
}
Zero Sum

 

USACO 2.3.4

题解:

背包改一改嘛(躺

f[j]表示构成j块钱的方案数,输出f[n]。

代码:

/*
ID:m1599491
PROG:money
LANG:C++
*/
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#define MaxN 10005
#define MaxV 30
#define ll long long
using namespace std;

ll v,n,m,f[MaxN];
int i,j;

main()
{
    freopen("money.in","r",stdin);
    freopen("money.out","w",stdout);
    scanf("%lld%lld",&v,&n);
    f[0]=1;
    for (i=1; i<=v; i++)
    {
        scanf("%lld",&m);
        for (j=m; j<=n; j++) f[j]+=f[j-m];
    }
    printf("%lld\n",f[n]);
}
Money Systems

 

USACO 2.3.5

题解:

DFS嘛,c[i]表示i公司被当前枚举到的公司控制的股份,如果c[i]>50就继续DFS下去,最后枚举一波,大于50的就直接输出了,然后就memset。(由于我是个傻逼,没有加头文件cstring,看着memset报错懵逼了好久

代码:

/*
ID:m1599491
PROG:concom
LANG:C++
*/
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

int f[110][110],c[110];
bool use[110]={0};
int n,i,x,y,z,m,j;

void dfs(int x)
{
    use[x]=1;
    int i;
    for (i=1; i<=n; i++) c[i]+=f[x][i];
    for (i=1; i<=n; i++) if (c[i]>50 && !use[i]) dfs(i);
}

main()
{
    freopen("concom.in","r",stdin);
    freopen("concom.out","w",stdout);
    scanf("%d",&m);
    for (i=1; i<=m; i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        f[x][y]=z;
        n=max(n,max(x,y));
    }
    for (i=1; i<=n; i++)
    {
        memset(c,0,sizeof(c));
        memset(use,false,sizeof(use));
        dfs(i);
        for (j=1; j<=n; j++) if (i!=j && c[j]>50) printf("%d %d\n",i,j);
    }
}
Controlling Companies
posted @ 2017-07-27 18:03  ALHDLIOX  阅读(139)  评论(0编辑  收藏  举报