腾讯机试题 AcWing 603 打怪兽

2021-06-07 11:19

阅读:459

标签:机试题   make   click   bsp   ==   tor   template   img   init   

题目链接:https://www.acwing.com/problem/content/605/

题目大意:

  略

分析:

  用dp[i][j]表示用j元钱能在前i只怪兽上所能贿赂到的最大武力值。

  有一种情况就是打到第i只怪兽所需的最低花费大于j,那么令dp[i][j] = -1。

  那么dp[i + 1][j],也就是同样用j元钱能在前i + 1只怪兽上所能贿赂到的最大武力值是多少呢?有3种情况:

    1:dp[i][j] = -1,显然dp[i + 1][j] = -1。

    2:dp[i][j]

      (1):j

      (2):dp[i][j - p[i + 1]] == -1,这说明腾不出钱来,于是dp[i + 1][j] = -1。

      (3):dp[i][j - p[i + 1]] != -1,那么dp[i + 1][j] = dp[i][j - p[i + 1]] + d[i + 1],不存在选择,必须贿赂。

    3:dp[i][j] >= d[i + 1],在这种情况下可以选择贿赂,也可以选择不贿赂,两种情况取最大即可,dp[i + 1][j] = max(dp[i][j], dp[i][j - p[i + 1]] + d[i + 1])。

  递推关系有了,现在需要第0列的初始值:除了第0行,其他全部为-1;和第0行的初始值:全部为0。

 

  那dp数组算出来了有啥用呢?

  假设你打到第i个怪的时候,武力值为D,这时D = d[i]的j,这个j一定是打前i个怪最优的,因为花费比j小的金钱过不了这个boss,如果这个j能一直保持到游戏结束,那这个j就是总体最优的。

代码如下:

技术图片技术图片
  1 #pragma GCC optimize("Ofast")
  2 #include   3 using namespace std;
  4  
  5 #define INIT() std::ios::sync_with_stdio(false);std::cin.tie(0);
  6 #define Rep(i,n) for (int i = 0; i   7 #define For(i,s,t) for (int i = (s); i   8 #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
  9 #define ForLL(i, s, t) for (LL i = LL(s); i  10 #define rForLL(i, t, s) for (LL i = LL(t); i >= LL(s); --i)
 11 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
 12 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
 13  
 14 #define pr(x) cout  15 #define prln(x) cout  16 #define EL() printf("\n")
 17 
 18 #define SORT(c, s, t) sort(c + s, c + t + 1)
 19  
 20 #define LOWBIT(x) ((x)&(-x))
 21  
 22 #define ALL(x) x.begin(),x.end()
 23 #define INS(x) inserter(x,x.begin())
 24  
 25 #define ms0(a) memset(a,0,sizeof(a))
 26 #define msI(a) memset(a,inf,sizeof(a))
 27 #define msM(a) memset(a,-1,sizeof(a))
 28  
 29 #define pii pair 30 #define piii pair,int>
 31 #define MP make_pair
 32 #define PB push_back
 33 #define ft first
 34 #define sd second
 35  
 36 template 37 istream &operator>>(istream &in, pair &p) {
 38     in >> p.first >> p.second;
 39     return in;
 40 }
 41  
 42 template 43 istream &operator>>(istream &in, vector &v) {
 44     for (auto &x: v)
 45         in >> x;
 46     return in;
 47 }
 48  
 49 template 50 ostream &operatorout, const std::pair &p) {
 51     out "[" ", " "]" "\n";
 52     return out;
 53 }
 54  
 55 typedef long long LL;
 56 typedef unsigned long long uLL;
 57 typedef pairdouble, double > PDD;
 58 typedef setint > SI;
 59 typedef vectorint > VI;
 60 const double EPS = 1e-10;
 61 const int inf = 1e9 + 9;
 62 const LL mod = 1e9 + 7;
 63 const int maxN = 1e5 + 7;
 64 const LL ONE = 1;
 65 
 66 //! n 表示怪兽的数量
 67 //! d[i] 表示第i只怪兽的武力值
 68 //! p[i] 表示收买第i只怪兽所需的金币数
 69 //! ans 最小花费 
 70 int n, p[57], ans;
 71 LL d[57];
 72 //! dp[i][j] 表示用j元钱能在前i只怪兽上所能贿赂到的最大武力值 
 73 LL dp[57][107];
 74 
 75 
 76 int main(){
 77     INIT();
 78     cin >> n;
 79     For(i, 1, n) cin >> d[i];
 80     For(i, 1, n) cin >> p[i];
 81     
 82     For(i, 1, n) dp[i][0] = -1; 
 83     
 84      For(j, 1, 2 * n) {
 85         For(i, 1, n) {
 86             if(dp[i - 1][j] == -1) dp[i][j] = -1;
 87             else if(dp[i - 1][j]  d[i]) {
 88                 if(j 1;
 89                 else if(dp[i - 1][j - p[i]] == -1) dp[i][j] = -1;
 90                 else dp[i][j] = dp[i - 1][j - p[i]] + d[i];
 91             }
 92             else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - p[i]] + d[i]);
 93         }
 94     }
 95     
 96     // maxD 最大武力值
 97     // maxDi 最大武力值下标 
 98     LL maxD = -1, maxDi;
 99     For(i, 1, n) {
100         if(d[i] > maxD) {
101             maxD = d[i];
102             maxDi = i;
103         } 
104     }
105     
106     ans = lower_bound(dp[maxDi], dp[maxDi] + 2 * n, maxD) - dp[maxDi]; 
107     
108     cout  endl;
109     return 0;
110 }
View Code

 

腾讯机试题 AcWing 603 打怪兽

标签:机试题   make   click   bsp   ==   tor   template   img   init   

原文地址:https://www.cnblogs.com/zaq19970105/p/10742586.html


评论


亲,登录后才可以留言!