SRM478

又是rng_58的神题。。

250pt:

题意:给定一个初始数x,对于这个数可以进行x*4+3,或者x*8+7的操作。最多进行100000次操作

       问最少经过几次出现%1000000007 == 0的情况。。

思路:

     x*4+3 = (x * 2 + 1) * 2 + 1

     x * 8 + 7 = (x * 4 + 3) * 2 + 1

     所以我们发现两个操作都可以合并成x * 2 + 1的操作。所以直接模拟30w次*2+1操作。

    如果操作y次*2+1那么答案便是(y + 2) / 3,注意y == 1时无解需特判

code:

 1 #line 7 "CarrotJumping.cpp"
 2 #include <cstdlib>
 3 #include <cctype>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <vector>
 9 #include <string>
10 #include <iostream>
11 #include <sstream>
12 #include <map>
13 #include <set>
14 #include <queue>
15 #include <stack>
16 #include <fstream>
17 #include <numeric>
18 #include <iomanip>
19 #include <bitset>
20 #include <list>
21 #include <stdexcept>
22 #include <functional>
23 #include <utility>
24 #include <ctime>
25 using namespace std;
26 
27 #define PB push_back
28 #define MP make_pair
29 
30 #define REP(i,n) for(i=0;i<(n);++i)
31 #define FOR(i,l,h) for(i=(l);i<=(h);++i)
32 #define FORD(i,h,l) for(i=(h);i>=(l);--i)
33 #define M 1000000007
34 typedef vector<int> VI;
35 typedef vector<string> VS;
36 typedef vector<double> VD;
37 typedef long long LL;
38 typedef pair<int,int> PII;
39 
40 
41 class CarrotJumping
42 {
43         public:
44         int theJump(int x)
45         { 
46              for (int i = 1; i <= 300000; ++i){
47                   x = (x * 2 + 1) % M;
48                   if (x == 0 && i >= 2) return (i + 2) / 3;   
49              }    
50              return -1;
51         }
52 };
View Code

500pt

题意:有N<=15个杯子,所有杯子的容量都是一样的,为C<50。现在已知每个杯子当前的水量,数量为x的杯子可以卖p[i]的钱。不过在卖之前可以做任意次操作:选两个杯子a和b,把a的水往b倒,知道a空了或者b满了为止。问这些杯子经过操作后,最多一共能卖多少钱。

思路: 如果选中若干个杯子,那么这些杯子的状态便是固定的,因为必须倒到满或者空。

         那么集合dp的感觉就很明显了

         dp[mask]表示选中mask状态个的被子最多卖多少钱。然后枚举子状态即可。。

code:

 1 #line 7 "KiwiJuice.cpp"
 2 #include <cstdlib>
 3 #include <cctype>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <vector>
 9 #include <string>
10 #include <iostream>
11 #include <sstream>
12 #include <map>
13 #include <set>
14 #include <queue>
15 #include <stack>
16 #include <fstream>
17 #include <numeric>
18 #include <iomanip>
19 #include <bitset>
20 #include <list>
21 #include <stdexcept>
22 #include <functional>
23 #include <utility>
24 #include <ctime>
25 using namespace std;
26 
27 #define PB push_back
28 #define MP make_pair
29 #define two(i) (1 << i)
30 #define REP(i,n) for(i=0;i<(n);++i)
31 #define FOR(i,l,h) for(i=(l);i<=(h);++i)
32 #define FORD(i,h,l) for(i=(h);i>=(l);--i)
33 
34 typedef vector<int> VI;
35 typedef vector<string> VS;
36 typedef vector<double> VD;
37 typedef long long LL;
38 typedef pair<int,int> PII;
39 int dp[1 << 16], cost[1 << 16];
40 class KiwiJuice
41 {
42         public:
43         int c, n;
44         vector<int> b, p;
45         void calculateCost(int mask){
46              int v = 0, bn = 0;
47              for (int i = 0; i < n; ++i)
48                  if (two(i) & mask){
49                        v += b[i];
50                        ++bn;
51                  }
52              cost[mask] = p[v % c] + (v / c) * p[c] + p[0] * (bn - v / c - 1);
53         }
54         int dfs(int mask){
55               if (dp[mask] != -1) return dp[mask];
56               dp[mask] = 0;
57               for (int i = mask; i; i = (i-1) & mask)
58                   dp[mask] = max(cost[i] + dfs(mask ^ i), dp[mask]);
59               return dp[mask];
60         }
61         int theProfit(int C, vector <int> bottles, vector <int> prices)
62         {
63                b = bottles, p = prices;
64                n = b.size(), c = C;
65                for (int i = 1; i < two(n); ++i)
66                    calculateCost(i);
67                memset(dp, -1, sizeof(dp));
68                return dfs(two(n) - 1);
69         }
70 };
View Code
原文地址:https://www.cnblogs.com/yzcstc/p/3627059.html