标签:决策 怎么 amp 程序 include span 数据 pac algorithm
通过读题,我们发现这道题与修筑长城非常的像,而修筑长城顺手修了一定更好,但是这道题中顺手将pizza送出并不能更好,可能会
“倒贴”,所以不能完全的像修筑长城那样解决问题,那么这道题怎么办呢?
又从读题中我们发现数据范围十分的小,并且单位时间内每个客户的费用相同,这就告诉我们可以增加状态的维度或者决策数来更加
贴近这道题,由于我们无法确定那个客户送pizza,那个客户不管,所以状态上必须有所体现。
我们设d(i,j,k,p)表示[i,j]区间不管(可能这个区间送出了pizza也可能没有)还要给k个用户送出pizza的最大收益,其中p为0时说明在i处,
p为1时说明在j处,状态转移方程看程序就行了,其中时间的求法非常巧妙,下面是代码:
// UVa 1628 #include <cstdio> #include <algorithm> #include <cmath> using namespace std; const int maxn = 100 + 5; int n, pos[maxn], v[maxn], kase; int d[maxn][maxn][maxn][2], vis[maxn][maxn][maxn][2]; int dp(int s, int e, int k, int p) { if (k == 0) return 0; int& ans = d[s][e][k][p]; if (vis[s][e][k][p] == kase) return ans; vis[s][e][k][p] = kase; ans = 0; if (!p) { for (int i = 0; i < s; ++i) ans = max(ans, v[i]-k*abs(pos[i]-pos[s])+dp(i,e,k-1,0)); for (int i = e+1; i < n; ++i) ans = max(ans, v[i]-k*abs(pos[i]-pos[s])+dp(s,i,k-1,1)); } else { for (int i = 0; i < s; ++i) ans = max(ans, v[i]-k*abs(pos[i]-pos[e])+dp(i,e,k-1,0)); for (int i = e+1; i < n; ++i) ans = max(ans, v[i]-k*abs(pos[i]-pos[e])+dp(s,i,k-1,1)); } return ans; } int main() { int t; scanf("%d", &t); for (kase = 1; kase <= t; ++kase) { scanf("%d", &n); for (int i = 0; i < n; ++i) scanf("%d", &pos[i]); for (int i = 0; i < n; ++i) scanf("%d", &v[i]); int ans = 0; for (int k = 1; k <= n; ++k) for (int i = 0; i < n; ++i) ans = max(ans, v[i]-k*abs(pos[i])+dp(i,i,k-1,0)); printf("%d\n", ans); } return 0; }
标签:决策 怎么 amp 程序 include span 数据 pac algorithm
原文地址:https://www.cnblogs.com/yifeiWa/p/11320202.html