Topcoder 658 650 point

Topcoder 658 div2 500 加强版

不过给了<=20,暴力肯定不行。

然后想DP方程,先二分可能需要的最大次数mid;

然后根据 mid 构造 DP方程。

假设x[i]需要 x个9 ,y个3,z个1,x*9+y*3+z>=x[i];

然后求出dp[n][[x]][y][z]<=mid 是否 符合。

转移方程为:dp[i+1][n9+m9][m3+n3]=min(dp[i+1][n9+m9][n3+m3],dp[i][n9][n3]+max(0,x[i]-9*m9-3*m3));

              (i<n,m9+n9<=mid,m3+n3<=mid)

这里是5维

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <algorithm>
 4 #include <fstream>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <cstring>
 8 #include <string>
 9 #include <ctime>
10 #include <queue>
11 #include <stack>
12 #include <vector>
13 #include <map>
14 #include <deque>
15 #include <set>
16 
17 using namespace std;
18 
19 int dp[22][151][151];
20 
21 class  Mutalisk
22 {
23     public:
24     int minimalAttacks(vector <int> x)
25     {
26 
27         int r=150,l=0;
28         int n=x.size();
29         for (int _=1;_<20;_++)
30         {
31             int mid=(l+r)>>1;
32             memset(dp,1,sizeof(dp));
33             dp[0][0][0]=0;
34             
35             for (int i=0;i<n;i++)
36             for (int n9=0;n9<=mid;n9++)
37             for (int n3=0;n3<=mid;n3++)
38             {
39                 if (dp[i][n9][n3]>mid ) continue;
40                 
41                 for (int m9=0;m9*9<=x[i]+8&&m9+n9<=mid;m9++)
42                 for (int m3=0;m3*3+m9*9<=max(m9*9,x[i]+2)&&m3+n3<=mid;m3++)
43                 {
44                     if (m9+m3+max(0,x[i]-9*m9-3*m3)>mid) continue;
45                     dp[i+1][n9+m9][m3+n3]=min(dp[i+1][n9+m9][n3+m3],dp[i][n9][n3]+max(0,x[i]-9*m9-3*m3));
46                 }
47             }
48 
49         int ok=0;
50         for (int n9=0;!ok&&n9<=mid;n9++)
51         for (int n3=0;!ok&&n3<=mid;n3++)
52         if (dp[n][n9][n3]<=mid)
53         {
54             ok=1;
55         }
56 
57         if (ok) r=mid;
58         else l=mid;
59         }
60         return r;
61     }
62 };
63 
64 int main()
65 {
66     int n;
67     cin>>n;
68     vector<int> p;
69     for (int i=1;i<=n;i++)
70     {
71         int x;
72         cin>>x;
73         p.push_back(x);
74     }
75     Mutalisk q;
76     cout<<q.minimalAttacks(p)<<endl;
77     return 0;
78 }

状态,需要剪枝。

原文地址:https://www.cnblogs.com/forgot93/p/4484703.html