1. 程式人生 > >6249 Alice’s Stamps (dp)

6249 Alice’s Stamps (dp)

Alice’s Stamps

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1169    Accepted Submission(s): 417  

Problem Description

Alice likes to collect stamps. She is now at the post office buying some new stamps. There are N different kinds of stamps that exist in the world; they are numbered 1 through N. However, stamps are not sold individually; they must be purchased in sets. There are M different stamp sets available; the ith set contains the stamps numbered Li through Ri. The same stamp might appear in more than one set, and it is possible that one or more stamps are not available in any of the sets. All of the sets cost the same amount; because Alice has a limited budget, she can buy at most K different sets. What is the maximum number of different kinds of stamps that Alice can get?

Input

The input starts with one line containing one integer T, the number of test cases.T test cases follow. Each test case begins with a line containing three integers: N, M, and K: the number of different kinds of stamps available, the number of stamp sets available, and the maximum number of stamp sets that Alice can buy. M lines follow; the ithoftheselinesrepresentsthei^{th} stamp set and contains two integers, Li and Ri, which represent the inclusive range of the numbers of the stamps available in that set. 1≤T≤100 1≤K≤M 1≤N,M≤2000 1≤Li≤Ri≤N

Output

For each test case, output one line containing “Case #x: y”, where x is the test case number (starting from 1) and y is the maximum number of different kinds of stamp that Alice could get.

Sample Input

2 5 3 2 3 4 1 1 1 3 100 2 1 1 50 90 100

Sample Output

Case #1: 4 Case #2: 50

Hint

In sample case #1, Alice could buy the first and the third stamp sets, which contain the first four kinds of stamp. Note that she gets two copies of stamp 3, but only the number of different kinds of stamps matters, not the number of stamps of each kind. In sample case #2, Alice could buy the first stamp set, which contains 50 different kinds of stamps.

題意:

給你n個點,m條線段,每個線段覆蓋一個區間的點(閉區間),問你選出k個區間最多能覆蓋多少個點。

思路:

剛開始想線段樹,無奈出題人喪心病狂,卡掉了多一個log的線段樹。

於是只能考慮n^2的dp。dp的狀態表示還是很好想的:

設dp[i][j]為右端點為i點,選j個區間所能覆蓋的最大點數。

顯然dp[i][j]要轉移到dp[k][j+1],就必須i+1點到k點是被一條線段覆蓋的,即你選的這條線段,而且k就是你選的這條線段的右端點。

對於每個點i,我們希望選的下一條線段能增加儘可能多的未覆蓋的點。因此在輸入每條線段時,標記每個點的值為覆蓋這個點的所有線段中右端點能延伸的最大值。設為you[i]

則就有

if(you[i+1]) dp[you[i+1]][j]=max(dp[you[i+1]][j],dp[i][j-1]+you[i+1]-i); if(i) dp[i][j]=max(dp[i][j],dp[i-1][j]); dp[i][j]=max(dp[i][j],dp[i][j-1]);

然後程式碼就很簡單了:(有疑問歡迎在評論區留言)

#include<bits/stdc++.h>
using namespace std;
const int maxn=2010;
int n,m,k;
struct line
{
    int l,r;
}a[maxn];
int you[maxn],dp[maxn][maxn];
int main()
{
    int i,j,cns,t;
    scanf("%d",&t);
    cns=1;
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&k);
        memset(you,0,sizeof(you));
        for(i=0;i<m;i++)
        {
            scanf("%d%d",&a[i].l,&a[i].r);
            for(int j=a[i].l;j<=a[i].r;j++)
            you[j]=max(you[j],a[i].r);
        }
        memset(dp,0,sizeof(dp));
        for(int i=0;i<n;i++)
        for(int j=1;j<=k;j++)
        {
            if(you[i+1]) dp[you[i+1]][j]=max(dp[you[i+1]][j],dp[i][j-1]+you[i+1]-i);
            if(i) dp[i][j]=max(dp[i][j],dp[i-1][j]);
            dp[i][j]=max(dp[i][j],dp[i][j-1]);
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        for(int j=1;j<=k;j++)
        ans=max(ans,dp[i][j]);
        printf("Case #%d: ",cns++);
        printf("%d\n",ans);
    }
}