码迷,mamicode.com
首页 > 其他好文 > 详细

UVa1628

时间:2019-08-08 13:09:41      阅读:74      评论:0      收藏:0      [点我收藏+]

标签:决策   怎么   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;
}

 

UVa1628

标签:决策   怎么   amp   程序   include   span   数据   pac   algorithm   

原文地址:https://www.cnblogs.com/yifeiWa/p/11320202.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!