Algorithm


problem Link : https://onlinejudge.org/index.php?option=onlinejudge&Itemid=8&page=show_problem&problem=1586 

Alfred wants to plan what to cook in the next days. He can cook various dishes. For each dish the costs of the ingredients and the benefit value is known. If a dish is cooked the second time in a row, the benefit value for the second time is 50 percent of the benefit value of first time, if it is prepared for the third or higher time in a row, the benefit value is 0. For example cooking a dish with benefit value v three times in a row leads to a total benefit value of 1.5 ∗ v. Help him to build the menu which maximizes the benefit value under the constraint that his budget is not exceeded. Input The input consists of several test cases. Each test case begins with 3 integers in a line: The number of days k (1 ≤ k ≤ 21) Alfred wants to plan for, the number of dishes n (1 ≤ n ≤ 50) he can cook and his budget m (0 ≤ m ≤ 100). The following n lines describe the dishes Alfred can cook. The i-th line contains two integers: the costs c (1 ≤ c ≤ 50) and the benefit value v (1 ≤ v ≤ 10000) of the i-th dish. The end of the input is signaled by a test case with k = n = m = 0. You don’t need to process this test case. Output For each output, print the maximum benefit value reachable with 1 digit after the decimal point. Then print k integers with i-th integer being the number of the dish to cook on day i. Dishes are numbered from 1 to n. Print at least one space or new line character after each integer. If there are several possible menus reaching the maximum benefit value, select the one with minimum costs, if there are several with minimum costs, you can print any of them. If every menu exceeds the budget, print only the benefit value of ‘0’.

Sample Input 2 1 5 3 5 3 5 20 2 5 18 6 1 1 3 3 2 3 0 0 0

Sample Output 0.0 13.0 1 5 1

Code Examples

#1 Code Example with C Programming

Code - C Programming

#include <bits/stdc++.h>
using namespace std;

struct node {
    int dish;
    node *prev;
};
// state: days, budget, dish, count
double dp[22][101][51][2];
node dp_path[22][101][51][2];

int main() {
    int k,n,m,c,v;
    while(scanf("%d %d %d",&k,&n,&m), (k+n+m)) {
        vector < pair<int,int>> dishes;
        for(int i=0;i < n;i++){
            scanf("%d %d",&c,&v);
            dishes.push_back({c,v});
        }
        for(int i=0;i < =k;i++) //day
            for(int j=0;j < n;j++) // dish
                for(int t=0;t < 2;t++) // repetition
                    for(int b=0;b < =m;b++) // budget
                        dp[i][b][j][t] = -1;

        double res = 0;
        int best_cost = INT_MAX;
        node *path;
        dp[0][0][0][0] = 0;
        dp_path[0][0][0][0].dish = -1;
        for(int i=0;i < =k;i++){ //day
            for(int j=0;j < n;j++){ // dish
                for(int t=0;t < 2;t++){ // repetition
                    for(int b=0;b < =m;b++){ // budget
                        if(i == k) {
                            if(dp[i][b][j][t]>res || (dp[i][b][j][t]==res && b<best_cost)) {
                                res = dp[i][b][j][t];
                                best_cost = b;
                                path = &dp_path[i][b][j][t];
                            }
                            continue;
                        }
                        if(dp[i][b][j][t] == -1) continue;
                        for(int p=0;p < n;p++){ // next dish
                            tie(c,v> = dishes[p];
                            int cost = b+c;
                            int times = 0;
                            if(cost > m) continue;
                            double benefit = dp[i][b][j][t];
                            if(i==0 || j!=p) benefit += v;
                            else if(j==p && t==0) benefit += v/2.0, times=1;
                            else times=1;
                            if(benefit > dp[i+1][cost][p][times]) {
                                dp[i+1][cost][p][times] = benefit;
                                dp_path[i+1][cost][p][times].dish = p;
                                dp_path[i+1][cost][p][times].prev = &dp_path[i][b][j][t];
                            }
                        }
                    }
                }
            }
        }
        printf("%.1f\n",res);
        if(res != 0.0) {
            stack < int> rev;
            while(path->dish != -1) {
                rev.push(path->dish+1);
                path = path->prev;
            }
            while(!rev.empty()){
                printf("%d", rev.top()), rev.pop();
                if(rev.empty()) printf("\n");
                else printf(" ");
            }
        }
    }
}
Copy The Code & Try With Live Editor

Input

x
+
cmd
2 1 5
3 5
3 5 20
2 5
18 6
1 1
3 3
2 3
0 0 0

Output

x
+
cmd
0.0
13.0
1 5 1
Advertisements

Demonstration


UVA Online Judge solution - 10645-Menu. - UVA Online Judge solution in C,C++,java

Previous
UVA Online Judge solution - 1064-Network - UVA Online Judge solution in C,C++,java
Next
UVA Online Judge solution - 10651-Pebble Solitaire - UVA Online Judge solution in C,C++,java