Particle

競技プログラミングについての雑記

AOJ 0597: Xiao Long Bao

解法

直近の順列に着目して、DPする

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
#define chmax(X,Y) X=max(X,Y)
#define N 200
map<vector<int>, int> dp[N];

int main(){
	int n;
	cin>>n;
	vector<int> d(n), a(n);
	for(int i = 0; i < n; i++) cin>>d[i];
	for(int i = 0; i < n; i++) cin>>a[i];
	int m = min(n, 7);
	vector<int> x(m);
	for(int i = 0; i < m; i++) x[i] = i;
	vector<int> y(x);
	do{
		int r = 0;
		for(int i = 0; i < m; i++)
			for(int j = max(0, i-d[i]); j <= min(m-1, i+d[i]); j++)
				if(x[i]<x[j]) r += a[i];
		dp[m][x] = r;
	} while(next_permutation(x.begin(), x.end()));
	for(int i = m; i < n; i++){
		x = vector<int>(y);
		do{
			int rr = dp[i][x];
			vector<int> x2(m);
			for(int j = 0; j < m-1; j++){
				x2[j] = x[j+1];
				if(x2[j]<x[0]) x2[j]++;
			}
			x2[m-1] = 0;
			for(int j = 0; j < m; j++){
				int r = rr;
				if(x[0]<x2[m-1] && m<=d[i-m]) r += a[i-m];
				else if(x[0]==x2[m-1]){
					int r1 = m<=d[i-m]?a[i-m]:0;
					int r2 = m<=d[i]?a[i]:0;
					r += max(r1, r2);
				} else if(x[0]>x2[m-1] && m<=d[i]) r += a[i];
				for(int k = 0; k < m-1; k++){
					int k2 = i-m+k+1;
					if(x2[k]<x2[m-1] && abs(m-1-k)<=d[k2]) r += a[k2];
					else if(x2[k]>x2[m-1] && abs(m-1-k)<=d[i]) r += a[i];
				}
				chmax(dp[i+1][x2], r);
				x2[m-1]++;
				for(int k = 0; k < m-1; k++)
					if(x2[k]==x2[m-1]) x2[k]--;
			}
		} while(next_permutation(x.begin(), x.end()));
	}
	x = vector<int>(y);
	int res = 0;
	do{
		chmax(res, dp[n][x]);
	} while(next_permutation(x.begin(), x.end()));
	cout<<res<<endl;
	return 0;
}