UVa 812 - Trade on Verweggistan (贪心+dfs)

题意:

题目给出一个w,表示几组货物,然后给你n以及n个数表示价格,利润=10-价格
每次只能取前i个,求最多的利润对应几个货物,如果答案超过10个,则升序输出前10个。

解析:

首先是简单的计算最大的利润,每行最大利润到那个位置,这样只要取每行的最大数的位置就好了,然后深搜出所有的可能。

AC代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 100;
vector<int> maxPos[N];
set<int> st;
int prul[N][N], maxv[N], sumv[N][N];
int w, b;
void init() {
    st.clear();
    for(int i = 0; i <= w; i++) {
        maxPos[i].clear();
    }
}
void dfs(int cur, int sum) {
    if(cur > w) {
        st.insert(sum);
        return ;
    }
    for(int i = 0; i < maxPos[cur].size(); i++) {
        dfs(cur+1, sum + maxPos[cur][i]);
    }
}
int main() {
    //freopen("in.txt", "r", stdin);
    int cas = 0, flag = 0;
    while(scanf("%d", &w) != EOF && w) {
        init();
        int maximum = 0;
        for(int i = 1; i <= w; i++) {
            scanf("%d", &b);
            sumv[i][0] = maxv[i] = 0;
            for(int j = 1; j <= b; j++) {
                scanf("%d", &prul[i][j]);
                sumv[i][j] = sumv[i][j-1] + (10-prul[i][j]);
                maxv[i] = max(maxv[i], sumv[i][j]);
            }
            maximum += maxv[i];
            if(maxv[i] == 0) maxPos[i].push_back(0);
            for(int j = 1; j <= b; j++) {
                if(sumv[i][j] == maxv[i]) {
                    maxPos[i].push_back(j);
                }
            }
        }
        dfs(1, 0);

        if(flag++) puts("");
        printf("Workyards %d\n", ++cas);
        printf("Maximum profit is %d.\n", maximum);
        printf("Number of pruls to buy:");
        set<int>::iterator it;
        int cnt = 0;
        for(it = st.begin(); it != st.end() && cnt < 10; it++, cnt++) {
            printf(" %d", *it);
        }puts("");
    }
    return 0;
}

你可能感兴趣的:(uva,812)