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\n",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\n",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 

 

 

posted @ 2013-11-07 00:27  byluoluo  阅读(193)  评论(0编辑  收藏  举报