• Contest 1


    hdu 4501 小明系列故事——买年货

    http://acm.hdu.edu.cn/showproblem.php?pid=4501

     每种商品只能选一次故为01背包。

    可以理解为有三个个背包(钱、积分总数、免费领取的件数),某件商品只要满足一种条件即可选取 。

    #include <cstdio>
    #include <cstring>
    #define N 105
    #define K 7

    int dp[N][N][N][K];
    int n, v1, v2, k;
    int c1[N], c2[N], val[N];

    int max(int x, int y)
    {
        return x > y ? x : y;
    }

    int main()
    {
        while(scanf("%d%d%d%d",&n, &v1, &v2, &k)!=EOF)
        {
            memset(dp, 0sizeof(dp));
            for(int i=1; i<=n; i++)
            {
                scanf("%d%d%d", &c1[i], &c2[i], &val[i]);
            }

            for(int i=1; i<=n; i++)
            {
                for(int j=0; j<=v1; j++)
                {
                    for(int a=0; a<=v2; a++)
                    {
                        for(int b=0; b<=k; b++)
                        {
                            int tmp = dp[i-1][j][a][b];
                            if(j>=c1[i])
                                tmp = max(tmp, dp[i-1][j-c1[i]][a][b]+val[i]); //开始的bug,原为if(j>=c1[i])tmp = max(dp[i-1][j][a][b], dp[i-1][j-c1[i]][a][b]+val[i]);
                            if(a>=c2[i])
                                tmp = max(tmp, dp[i-1][j][a-c2[i]][b]+val[i]);
                            if(b>=1)
                                tmp = max(tmp, dp[i-1][j][a][b-1]+val[i]);
                            dp[i][j][a][b] = tmp;

                        }
                    }
                }
            }
            printf("%d ",dp[n][v1][v2][k]);
        }
        return 0;
    }
    View Code 

     hdu 4502 吉哥系列故事——临时工计划

    http://acm.hdu.edu.cn/showproblem.php?pid=4502

     简单贪心。

    dp[i]表示前i份工作中第i份必选所获的最大工资。

    则dp[i]  = max(dp[j] + job[i].c) (job[i].s > job[j].e ,  0<= j <i) 。

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #define N 1005

    struct Job
    {
        int s, e, c;
    }job[N];

    int dp[N];

    int cmp(const void * a, const void * b)
    {
        struct Job *x = (struct Job *)a;
        struct Job *y = (struct Job *)b;
        if(x->s == y->s)
            return x->e - y->e;
        else
            return x->s - y->s;
    }

    int main()
    {
        int T, n, m, x, y, z, index;
        scanf("%d",&T);
        while(T--)
        {
            index = 0;
            memset(dp, 0sizeof(dp));
            scanf("%d%d", &m, &n);
            for(int i=0; i<n; i++)
            {
                scanf("%d%d%d",&x, &y, &z);
                if(y <= m)
                {
                    job[++index].s = x;
                    job[index].e = y;
                    job[index].c = z;
                }
            }
            qsort(job+1, index, sizeof(struct Job), cmp);

            job[0].s = job[0].e = job[0].c;
            int ans = 0;
            for(int i=1; i<=index; i++)
            {
                for(int j=0; j<i; j++)
                {
                    if(job[i].s > job[j].e && dp[j] + job[i].c > dp[i])
                        dp[i] = dp[j] + job[i].c;
                }
                if(ans < dp[i])ans = dp[i];
            }
            printf("%d ",ans);

        }
        return 0;
    }
    View Code 

     hdu 4504 威威猫系列故事——篮球梦

    http://acm.hdu.edu.cn/showproblem.php?pid=4504

    组合题。

     a为要拿的分数,n为可以得分的轮数(每轮从1、2、3中取值)

    (1)a<=n :ans = 3^n;

    (2)a>3*n: ans = 0; 

    (3)n<a<=3*n: 得分q可取 a <=q<=3*n  

    另q=q-n,问题转化为把q分成k1个1,k2个2并在n个位子中选位插入的情况种数。 注意k1+k2<=n。

    枚举一遍即可。

    #include <iostream>
    using namespace std;

    long long C(long long n, long long a)
    {
        if(2*a>n)
            a = n - a;
        long long ret = 1;
        for(int i=0; i<a; i++)
            ret *= n - i;
        for(int i=0; i<a; i++)
            ret /= a - i;
        return ret;
    }

    int main()
    {
        long long a, b, t, n, k;
        while(cin >> a >> b >> t)
        {
            long long ans = 0;
            a = b - a;
            t = t / 15;
            a += t / 2 + 1;
            n = ( t + 1 ) / 2;
            if(a<=n)
            {
                ans = 1;
                for(long long i=1; i<=n; i++)
                    ans *= 3;
            }
            else if(a > 3*n)
                ans = 0;
            else
            {
                for(long long q=a; q<=3*n; q++)
                {
                    long long tmp = q;
                    tmp -= n;
                    k = tmp / 2;//最多k个2
                    for(long long i=0; i<=k; i++)
                    {
                        long long j = tmp - 2 * i;
                        if(i+j>n) continue;
                        ans += C(n, i) * C(n-i, j);
                    }
                }
            }
            cout << ans << endl;
        }
        return 0;
    }
    View Code 
  • 相关阅读:
    CF1236B Alice and the List of Presents |数学
    luogu P1832 A+B Problem |背包
    CF832D Misha, Grisha and Underground |LCA
    bzoj1709[Usaco2007 Oct]Super Paintball超级弹珠*
    bzoj3314[Usaco2013 Nov]Crowded Cows*
    bzoj4300绝世好题
    bzoj2101[Usaco2010 Dec]Treasure Chest 藏宝箱*
    bzoj3437小P的牧场
    bzoj2016[Usaco2010]Chocolate Eating*
    bzoj2015[Usaco2010 Feb]Chocolate Giving*
  • 原文地址:https://www.cnblogs.com/byluoluo/p/3411591.html
Copyright © 2020-2023  润新知