北大校赛提前热身,Happy Programming Contest和Digging

做了两个DP的题目,本来没写出来,后来一个过了,仔细一想,这俩题是一样的,于是稍微改了下代码,第二个就过了。

题目连接

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3689

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3703

题目是酱紫

Happy Programming Contest
Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

Description

In Zhejiang University Programming Contest, a team is called "couple team" if it consists of only two students loving each other. In the contest, the team will get a lovely balloon with unique color for each problem they solved. Since the girl would prefer pink balloon rather than black balloon, each color is assigned a value to measure its attractiveness. Usually, the boy is good at programming while the girl is charming. The boy wishes to solve problems as many as possible. However, the girl cares more about the lovely balloons. Of course, the boy's primary goal is to make the girl happy rather than win a prize in the contest.

Suppose for each problem, the boy already knows how much time he needs to solve it. Please help him make a plan to solve these problems in strategic order so that he can maximize the total attractiveness value of balloons they get before the contest ends. Under this condition, he wants to solve problems as many as possible. If there are many ways to achieve this goal, he needs to minimize the total penalty time. The penalty time of a problem is equal to the submission time of the correct solution. We assume that the boy is so clever that he always submit the correct solution.

Input

The first line of input is an integer N (N < 50) indicating the number of test cases. For each case, first there is a line containing 2 integersT (T <= 1000) and n (n <= 50) indicating the contest length and the number of problems. The next line contains n integers and the i-th integer ti (ti <= 1000) represents the time needed to solve the ith problem. Finally, there is another line containing n integers and the i-th integer vi (vi <= 1000) represents the attractiveness value of the i-th problem. Time is measured in minutes.

Output

For each case, output a single line containing 3 integers in this order: the total attractiveness value, the number of problems solved, the total penalty time. The 3 integers should be separated by a space.

Sample Input

2
300 10
10 10 10 10 10 10 10 10 10 10
1 2 3 4 5 6 7 8 9 10
300 10
301 301 301 301 301 301 301 301 301 301
1000 1000 1000 1000 1000 1000 1000 1000 1000 1000

Sample Output

55 10 550
0 0 0
大概说,每个题有一个val值,和cost是需要消耗的时间,你有T个时间,需要获得最大的val值,如果有多种方法,要求做出的题目最多,如果还有多种方法,要求罚时最少,罚时是提交这个题的那个时间,并且这哥们挺牛逼,每次都是1Y。


看出来是DP,

dp【i】【j】指处理到第i道题目的时候,剩余j个时间的状态下最好的情况,这个情况包括的内容就是上面描述的val和题目数和罚时,然后状态转移就是i题做还是不做,两个方程。没有了,最后dp[n][...]的最优值就是答案。(我的课程是从0到n-1的)


感觉没有问题,wa了7次。

后来我盯了好几个小时终于看出来错了,罚时的计算出问题了。因为按照我的做法,是按照从0到n-1的顺序做题的,比如我做1,2,3题,和做3,2,1题罚时明显是不一样的,所以这里要用一个贪心,cost小的题目先做,这样我先给所有的题目排个序,然后在DP,就愉快的AC了。

这是想到了另一个题,和这个类似,于是也过了。

G - Digging
Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

Description

When it comes to the Maya Civilization, we can quickly remind of a term called the end of the world. It's not difficult to understand why we choose to believe the prophecy (or we just assume it is true to entertain ourselves) if you know the other prophecies appeared in theMaya Calendar. For instance, it has accurately predicted a solar eclipse on July 22, 2009.

The ancient civilization, such as Old BabylonianhasAncient Egypt and etc, some features in common. One of them is the tomb because of the influence of the religion. At that time, the symbol of the tomb is the pyramid. Many of these structures featured a top platform upon which a smaller dedicatory building was constructed, associated with a particular Maya deity. Maya pyramid-like structures were also erected to serve as a place of interment for powerful rulers.

Now there are N coffin chambers in the pyramid waiting for building and the ruler has recruited some workers to work for T days. It takesti days to complete the ith coffin chamber. The size of the ith coffin chamber is si. They use a very special method to calculate the reward for workers. If starting to build the ith coffin chamber when there are t days left, they can get t*si units of gold. If they have finished a coffin chamber, then they can choose another coffin chamber to build (if they decide to build the ith coffin chamber at the time t, then they can decide next coffin chamber at the time t-ti).

At the beginning, there are T days left. If they start the last work at the time t and the finishing time t-ti < 0, they will not get the last pay.

Input

There are few test cases.

The first line contains NT (1 ≤ N ≤ 3000,1 ≤ T ≤ 10000), indicating there are N coffin chambers to be built, and there are T days for workers working. Next N lines contains tisi (1 ≤ tisi ≤ 500).

All numbers are integers and the answer will not exceed 2^31-1.

Output

For each test case, output an integer in a single line indicating the maxminal units of gold the workers will get.

Sample Input
3 10
3 4
1 2
2 1
Sample Output
62
Hint

Start the second task at the time 10
Start the first task at the time 9
Start the third task at the time 6
The answer is 10*2+9*4+6*1=62


这个题是说有n个工程,完成每个的时间是ti,回报是开始这个工程是你剩余的时间乘以这个工程的si值,这些值会给你。

DP的方法一样,dp[i][j],处理第i个工程是有j个时间。

这个贪心有点不一样,需要稍微推导一下,这个和我去年区域赛上的一个贪心题很像,假设ab两个工程,算先做a和先做b的回报差,最后发现是按照a.s*b.t排序,然后DP,果断AC


贴代码


第一个


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

int t,n;
typedef struct no
{
    int cost;
    int happy;
} NODE;

NODE node[55];

bool cmp(const NODE &a,const NODE &b)
{
    return a.cost<b.cost;
}

int val[55][1010];//50题,1000时间,最大的值
int num[55][1010];//做的题数
int pen[55][1010];//罚时


void init()
{
    scanf("%d %d",&t,&n);
    for(int i=0; i<n; i++)
        scanf("%d",&node[i].cost);
    for(int i=0; i<n; i++)
        scanf("%d",&node[i].happy);
    memset(val,0,sizeof(val));
    memset(num,0,sizeof(num));
    memset(pen,0,sizeof(pen));
    sort(node,node+n,cmp);
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        init();
        for(int i=0; i<n; i++) //第i个题还有j个时间
        {
            for(int j=0; j<=t; j++)
            {
                if(node[i].cost<=j)//做
                {
                    int k=j-node[i].cost;
                    int next=val[i+1][k];
                    int flag=0;
                    if(next<val[i][j]+node[i].happy)
                        flag=1;
                    else if(next==val[i][j]+node[i].happy)
                    {
                        if(num[i+1][k]<num[i][j]+1)
                            flag=1;
                        else if(num[i+1][k]==num[i][j]+1)
                            if(pen[i+1][k]>pen[i][j]+(t-k))
                                flag=1;
                    }
                    if(flag)
                    {
                        val[i+1][k]=val[i][j]+node[i].happy;
                        num[i+1][k]=num[i][j]+1;
                        pen[i+1][k]=pen[i][j]+(t-k);
                    }
                }

                //不做
                int next=val[i+1][j];
                int flag=0;
                if(next<val[i][j])
                    flag=1;
                else if(next==val[i][j])
                {
                    if(num[i+1][j]<num[i][j])
                        flag=1;
                    else if(num[i+1][j]==num[i][j])
                        if(pen[i+1][j]>pen[i][j])
                            flag=1;
                }
                if(flag)
                {
                    val[i+1][j]=val[i][j];
                    num[i+1][j]=num[i][j];
                    pen[i+1][j]=pen[i][j];
                }
            }
        }
        int k=0;
        for(int i=1; i<=t; i++)
        {
            if(val[n][i]>val[n][k])
                k=i;
            else if(val[n][i]==val[n][k])
            {
                if(num[n][i]>num[n][k])
                    k=i;
                else if(num[n][i]==num[n][k])
                    if(pen[n][i]<pen[n][k])
                        k=i;
            }
        }
        printf("%d %d %d\n",val[n][k],num[n][k],pen[n][k]);
    }
    return 0;
}

第二个

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

int T,n;
typedef struct no
{
    int s;
    int t;
} NODE;

NODE node[3010];

bool cmp(const NODE &a,const NODE &b)
{
    return a.s*b.t>b.s*a.t;
}

int dp[2][10010];

void init()
{
    for(int i=0; i<n; i++)
        scanf("%d %d",&node[i].t,&node[i].s);
    memset(dp,0,sizeof(dp));
    sort(node,node+n,cmp);
}

int main()
{
    while((scanf("%d %d",&n,&T))!=EOF)
    {
        init();
        for(int x=0; x<n; x++) //第i个题还有j个时间
        {
            for(int j=0; j<=T; j++)
            {
                int i=x%2, k=(x+1)%2;
                dp[k][j] = max(dp[k][j],dp[i][j]);//no
                if(node[x].t<=j)//yes
                {
                    if(dp[i][j]+j*node[x].s>dp[k][j-node[x].t])
                        dp[k][j-node[x].t]=dp[i][j]+j*node[x].s;
                }
            }
        }
        int ans=dp[n%2][0];
        for(int i=1; i<=T; i++)
            ans=max(ans,dp[n%2][i]);
        printf("%d\n",ans);
    }
    return 0;
}


我发现出样例的人总是会弄的你怎么写都能过,一交就wa。



水平有限,众神轻喷。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值