2018牛客多校第三场A

记录路径的01背包,dp[i][j][k][l] 代表的是在余量为i, j, k, l 时最多可以容纳多少,那么显然,临界情况如果是x,那么对于四个参数均大于临界情况的时候,dp的值一定大于x

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

const int N = 40;

int dp[N][N][N][N];
int p[N], a[N], c[N], m[N], g[N];
bool path[N][N][N][N][N];

int main(){
	int n;
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> p[i] >> a[i] >> c[i] >> m[i] >> g[i];
	}
	int P, A, C, M;
	cin >> P >> A >> C >> M;
	for(int t = 1; t <= n; t ++){
		for(int i = P; i >= p[t]; i --){
			for(int j = A; j >= a[t]; j --){
				for(int k = C; k >= c[t]; k --){
					for(int l = M; l >= m[t]; l --){
						if(dp[i][j][k][l] < dp[i - p[t]][j - a[t]][k - c[t]][l - m[t]] + g[t]){
							dp[i][j][k][l] = dp[i - p[t]][j - a[t]][k - c[t]][l - m[t]] + g[t];
							path[t][i][j][k][l] = true;
						}
					}
				}
			}
		}
	}
	vector <int> ans;
	for(int t = n, i = P, j = A, k = C, l = M; t >= 1 && i >= 0 && j >= 0 && k >= 0 && l >= 0; t --){
		if(path[t][i][j][k][l]){
			ans. push_back(t);
			i -= p[t];
			j -= a[t];
			k -= c[t];
			l -= m[t];
		}
	}
	cout << ans. size() << endl;
	for(int i = ans. size() - 1; i >= 0; i --){
		cout << ans[i] - 1 << endl;
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_38759433/article/details/81458752