WOJ Problem 1537 - A - Stones I , Problem 1538 - B - Stones II

Problem 1537 - A - Stones I

Time Limit: 1000MS   Memory Limit: 65536KB   
Total Submit: 491  Accepted: 90  Special Judge: No

Description

Xiaoming took the flight MH370 on March 8, 2014 to China to take the ACM contest in WHU. Unfortunately, when the airplane crossing the ocean, a beam of mystical light suddenly lit up the sky and all the passengers with the airplane were transferred to another desert planet.

When waking up, Xiaoming found himself lying on a planet with many precious stones. He found that:

There are n precious stones lying on the planet, each of them has 2 positive values ai and bi. Each time Xiaoming can take the ith of the stones ,after that, all of the stones’ aj (including the stones Xiaoming has taken) will cut down bi units.

Xiaoming could choose arbitrary number (zero is permitted) of the stones in any order. Thus, he wanted to maximize the sum of all the stones he has been chosen. Please help him.

Input

The input consists of one or more test cases.

First line of each test case consists of one integer n with 1 <= n <= 1000.
Then each of the following n lines contains two values ai and bi.( 1<= ai<=1000, 1<= bi<=1000)
Input is terminated by a value of zero (0) for n. 

Output

For each test case, output the maximum of the sum in one line.

Sample Input

1
100 100
3
2 1
3 1
4 1
0

Sample Output

0
3

Hint

Source

题目大意:有一堆石头,每个石头有ai与bi值,我们每拿起一个石头,获得ai价值,同时所有的石头的ai值都会减去一个bi值(包括你已经拿的),问你拿的石头的价值最大为多少

题解:从1-n枚举你拿了k个石头,然后对ai-k*bi进行排序(k为你决定拿石头的总数),选前k个求和,取最大值。

#include<iostream>
#include <cstdio>
#include<stack>
#include <cstring>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define mem(a,x) memset(a,x,sizeof(a))
#define LL  long long

struct node
{
    int a,b;
}t[1010];
int c,n;

int dp[1010];

bool com(node x,node y)
{
    return x.a-c*x.b>y.a-c*y.b;
}

int main()
{
    while(~scanf("%d",&n))
    {
        int ans=0;
        F(i,1,n)
            scanf("%d%d",&t[i].a,&t[i].b);
        mem(dp,0);
        F(i,0,n-1)
        {
            sort(t+1,t+n+1,com);
            F(j,1,i)
            {
                dp[i]+=t[j].a-i*t[j].b;
            }
            if(dp[i]>ans) ans=dp[i];
        }
        printf("%d\n",ans);

    }
    return 0;
}

Problem 1538 - B - Stones II

题意:与A基本相同,只是你每次拿完石头后,剩下没被拿的石头的价值-bi

题解:对bi进行排序,因为在确定拿哪些石头的情况下,先拿bi小的肯定价值最大,接下来是01背包问题,这块石头你要么拿要么不拿,

          状态转移方程dp[i][j]=max(dp[i-1][j],dp[i-1][j+1]+a[i]-j*b[i]);

          i为现在是第几块石头,j为你还需要再拿几块石头

#include<iostream>
#include <cstdio>
#include<stack>
#include <cstring>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define mem(a,x) memset(a,x,sizeof(a))
#define LL  long long

struct node
{
    int a,b;
}t[1010];
int c,n;

int dp[1010][1010];

bool com(node x,node y)
{
    return x.b<y.b;
}

int main()
{
    while(scanf("%d",&n)&&n)
    {
        int ans=0;
        F(i,1,n)
            scanf("%d%d",&t[i].a,&t[i].b);
        mem(dp,0);
        sort(t+1,t+n+1,com);
        F(i,1,n)
            F(j,0,n-i)
                dp[i][j]=max(dp[i-1][j],dp[i-1][j+1]+t[i].a-j*t[i].b);

        printf("%d\n",dp[n][0]);

    }
    return 0;
}

因为没有找到题目链接,所以不知道代码准确度,但样例和思路是对的,如有错误,望指点

猜你喜欢

转载自blog.csdn.net/qq_41758381/article/details/82594407
今日推荐