我是记 fi,j,k,l 表示处理到第 i 个箱子,所有钥匙的残余流量为 j,选到了第 k 把钥匙,箱子残余流量为 l 的最小代价。
看了半天没看出错误,球球大佬帮我看看嘛
#include<bits/stdc++.h>
#define int long long
#define N 10
using namespace std;
int n, m, ans = 1e18;
int a[N], b[N], c[N][N], cnt;
vector<int>now, z, p[100005], r;
int f[8][16000][7][7];
map<vector<int>, int>num;
void dfs(int k) {
if(k > m) {
//for(auto x : z) cout << x << " ";
//cout << endl;
p[++cnt] = z;
num[z] = cnt;
for(int i = 1; i <= n + 1; i++)
for(int j = 1; j <= m; j++)
for(int l = 0; l <= 4; l++)
f[i][cnt][j][l] = 1e18;
return;
}
for(int i = 0; i <= b[k]; i++) {
z.push_back(i);
dfs(k + 1);
z.pop_back();
}
}
void upd(int &x, int y) {
x = min(x, y);
}
signed main() {
//ios::sync_with_stdio(false);
//cin.tie(0); cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= m; i++) cin >> b[i], now.push_back(b[i]);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) cin >> c[i][j];
dfs(1);
//cout << cnt << endl;
//cout << num[now] << endl;
f[1][num[now]][1][a[1]] = 0;
for(int i = 1; i <= n; i++) {
for(int k = 1; k <= m; k++) {
for(int j = 1; j <= cnt; j++) {
for(int l = 0; l <= a[i]; l++) {
if(k != m) {
upd(f[i][j][k + 1][l], f[i][j][k][l]);
int use = min(l, p[j][k - 1]);
r = p[j];
r[k - 1] -= use;
upd(f[i][num[r]][k + 1][l - use], f[i][j][k][l] + c[i][k]);
}
else {
if(l == 0) upd(f[i + 1][j][1][a[i + 1]], f[i][j][k][l]);
else if(p[j][k - 1] >= l) {
r = p[j];
r[k - 1] -= l;
upd(f[i + 1][num[r]][1][a[i + 1]], f[i][j][k][l] + c[i][k]);
}
}
}
}
}
}
/*for(int i = 1; i <= n; i++) {
for(int j = 1; j <= cnt; j++) {
for(int k = 1; k <= m; k++) {
for(int l = 0; l <= a[i]; l++) {
if(f[i][j][k][l] == 1e18) continue;
printf("f[%lld][%lld][%lld][%lld] = %lld\n", i, j, k, l, f[i][j][k][l]);
}
}
}
}*/
for(int i = 1; i <= cnt; i++) ans = min(ans, f[n + 1][i][1][0]);
if(ans == 1e18) cout << -1;
else cout << ans;
return 0;
}
/*
2 3
3 3
1 1 4
10 20 100
20 15 80
*/