Codeforces Round #436 (Div. 2) E. Fire(01揹包+輸出路徑)

Polycarp is in really serious trouble — his house is on fire! It's time to save the most valuable items. Polycarp estimated that it would take tiseconds to save i-th item. In addition, for each item, he estimated the value of di — the moment after which the item i will be completely burned and will no longer be valuable for him at all. In particular, if ti ≥ di, then i-th item cannot be saved.

Given the values pi for each of the items, find a set of items that Polycarp can save such that the total value of this items is maximum possible. Polycarp saves the items one after another. For example, if he takes item a first, and then item b, then the item a will be saved in taseconds, and the item b — in ta + tb seconds after fire started.

Input

The first line contains a single integer n (1 ≤ n ≤ 100) — the number of items in Polycarp's house.

Each of the following n lines contains three integers ti, di, pi (1 ≤ ti ≤ 201 ≤ di ≤ 2 0001 ≤ pi ≤ 20) — the time needed to save the itemi, the time after which the item i will burn completely and the value of item i.

Output

In the first line print the maximum possible total value of the set of saved items. In the second line print one integer m — the number of items in the desired set. In the third line print m distinct integers — numbers of the saved items in the order Polycarp saves them. Items are 1-indexed in the same order in which they appear in the input. If there are several answers, print any of them.

Examples
input
3
3 7 4
2 6 5
3 7 6
output
11
2
2 3 
input
2
5 6 1
3 3 5
output
1
1
1 

題意:發生了火災,現在有n個物品需要搶救。每個物品有搶救的時間和最晚時刻,還有價值。

讓求最大能搶救出來物品的價值,還有物品的個數,還要輸出這些物品。


我們可以用dp[i][j]表示取到第i個物品以時刻j爲結束時間的最大價值,然後就會發現這其實就是一個01揹包。

因爲要輸出路徑,所以用一個pre數組取存一下什麼狀態是存在的,然後遞歸輸出。


還有就是要注意一下最後求最大價值的時候ans要初始化爲小於0的數,如果初始化爲0的話,就找不到一個起始點來遞歸,就會RE。

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;


struct node
{
    int t,d,v,i;

}a[110];

bool cmp(node a,node b)
{
    if(a.d != b.d)
        return a.d < b.d;
    return a.v < b.v;
}

int dp[110][2200];
int pre[110][2200];


void print(int i,int j,int cnt)
{
    if(i == 0)
    {
        printf("%d\n",cnt);
        return;
    }
    if(pre[i][j] == 0)
    {
        print(i-1,j,cnt);
    }
    else
    {
        print(i-1,j-a[i].t,cnt+1);
        printf("%d ",a[i].i);
    }
}
int main(void)
{
    int n,i,j;
    while(scanf("%d",&n)==1)
    {
        for(i=1;i<=n;i++)
        {
            scanf("%d%d%d",&a[i].t,&a[i].d,&a[i].v);
            a[i].i = i;
        }
        sort(a+1,a+n+1,cmp);
        memset(pre,0,sizeof(pre));
        memset(dp,0,sizeof(dp));
        for(i=1;i<=n;i++)
        {
            for(j=0;j<=2000;j++)
            {
                dp[i][j] = dp[i-1][j];
                if(j >= a[i].t && j <= a[i].d - 1)
                {
                    if(dp[i][j] < dp[i-1][j-a[i].t] + a[i].v)
                    {
                        dp[i][j] = dp[i-1][j-a[i].t] + a[i].v;
                        pre[i][j] = 1;
                    }
                }
            }
        }
        int ans = -1;
        int c;
        for(i=0;i<=2000;i++)
        {
            if(dp[n][i] > ans)
            {
                ans = dp[n][i];
                c = i;
            }
        }
        cout << ans << endl;
        print(n,c,0);
        cout << endl;
    }

    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章