SRM 410(1-250pt, 1-500pt)

DIV1 250pt

题意:对于图G,有一些点和边,点中有一些点称为特殊点。问在所有特殊点最终不能处于同一个联通块的条件下,最多能给在图G中添加多少条边。

解法:首先,对于图G,处理出它有哪些联通块,然后,不含有特殊点的联通块要连接到某一个含有特殊点的联通块上。连接哪一个能使添加的边最多呢?当然是连接含有点数最多的含特殊点的联通块。

tag:graph, greedy

  1 // BEGIN CUT HERE
  2 /*
  3  * Author:  plum rain
  4  * score :
  5  */
  6 /*
  7 
  8  */
  9 // END CUT HERE
 10 #line 11 "AddElectricalWires.cpp"
 11 #include <sstream>
 12 #include <stdexcept>
 13 #include <functional>
 14 #include <iomanip>
 15 #include <numeric>
 16 #include <fstream>
 17 #include <cctype>
 18 #include <iostream>
 19 #include <cstdio>
 20 #include <vector>
 21 #include <cstring>
 22 #include <cmath>
 23 #include <algorithm>
 24 #include <cstdlib>
 25 #include <set>
 26 #include <queue>
 27 #include <bitset>
 28 #include <list>
 29 #include <string>
 30 #include <utility>
 31 #include <map>
 32 #include <ctime>
 33 #include <stack>
 34 
 35 using namespace std;
 36 
 37 #define clr0(x) memset(x, 0, sizeof(x))
 38 #define clr1(x) memset(x, -1, sizeof(x))
 39 #define pb push_back
 40 #define sz(v) ((int)(v).size())
 41 #define all(t) t.begin(),t.end()
 42 #define zero(x) (((x)>0?(x):-(x))<eps)
 43 #define out(x) cout<<#x<<":"<<(x)<<endl
 44 #define tst(a) cout<<a<<" "
 45 #define tst1(a) cout<<#a<<endl
 46 #define CINBEQUICKER std::ios::sync_with_stdio(false)
 47 
 48 typedef vector<int> vi;
 49 typedef vector<string> vs;
 50 typedef vector<double> vd;
 51 typedef pair<int, int> pii;
 52 typedef long long int64;
 53 
 54 const double eps = 1e-8;
 55 const double PI = atan(1.0)*4;
 56 const int inf = 2139062143 / 2;
 57 
 58 class AddElectricalWires
 59 {
 60     public:
 61         int f[100];
 62         bool v[100];
 63 
 64         int find(int x)
 65         {
 66             if (x != f[x]) f[x] = find(f[x]);
 67             return f[x];
 68         }
 69 
 70         int maxNewWires(vector <string> p, vector <int> num){
 71             clr0 (v);
 72             for (int i = 0; i < sz(num); ++ i) v[num[i]] = 1;
 73             for (int i = 0; i < sz(p); ++ i) f[i] = i;
 74             for (int i = 0; i < sz(p); ++ i)
 75                 for (int j = 0; j < sz(p); ++ j) if (p[i][j] == '1'){
 76                     int t1 = find(i), t2 = find(j);
 77                     if ((v[t1] && v[t2]) || (t1 == t2)) continue;
 78                     if (!v[t1]) f[t1] = t2;
 79                     else f[t2] = t1;
 80 
 81                 }
 82             int ans = 1, idx = num[0];
 83             for (int i = 0; i < sz(num); ++ i){
 84                 int tmp = 0;
 85                 for (int j = 0; j < sz(p); ++ j)
 86                     if (find(j) == num[i]) ++ tmp;
 87                 if (tmp > ans)
 88                     idx = num[i], ans = tmp;
 89             }
 90             int ret = 0;
 91             for (int i = 0; i < sz(p); ++ i)
 92                 for (int j = i+1; j < sz(p); ++ j) if (p[i][j] == '0'){
 93                     int t1 = find(i), t2 = find(j);
 94                     if (t1 == t2){
 95                         ++ ret; continue;
 96                     }
 97                     if (v[t1] && v[t2]) continue;
 98                     if (!v[t1] && !v[t2]){
 99                         ++ ret; f[t1] = t2; continue;
100                     }
101                     if (t1 == idx || t2 == idx){
102                         ++ ret;
103                         if (t1 == idx) f[t2] = idx;
104                         else f[t1] = idx;
105                     }
106                 }
107             return ret;
108         }
109         
110 // BEGIN CUT HERE
111     public:
112     void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); }
113     private:
114     template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '"' << *iter << "","; os << " }"; return os.str(); }
115     void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "	Expected: "" << Expected << '"' << endl; cerr << "	Received: "" << Received << '"' << endl; } }
116     void test_case_0() { string Arr0[] = {"000","000","000"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 3; verify_case(0, Arg2, maxNewWires(Arg0, Arg1)); }
117     void test_case_1() { string Arr0[] = {"000","000","000"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0,1}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 1; verify_case(1, Arg2, maxNewWires(Arg0, Arg1)); }
118     void test_case_2() { string Arr0[] = {"01","10"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 0; verify_case(2, Arg2, maxNewWires(Arg0, Arg1)); }
119     void test_case_3() { string Arr0[] = {"00000","00000","00000","00000","00000"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0,1,2,3,4}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 0; verify_case(3, Arg2, maxNewWires(Arg0, Arg1)); }
120     void test_case_4() { string Arr0[] = {"01000","10100","01010","00100","00000"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {2,4}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 3; verify_case(4, Arg2, maxNewWires(Arg0, Arg1)); }
121 
122 // END CUT HERE
123 
124 };
125 
126 // BEGIN CUT HERE
127 int main()
128 {
129 //    freopen( "a.out" , "w" , stdout );    
130     AddElectricalWires ___test;
131     ___test.run_test(-1);
132        return 0;
133 }
134 // END CUT HERE
View Code

DIV1 500pt

题意:给定整数k,n和一个数组A[],要按顺序访问范围为0-(n-1)的数轴上编号为A[i]的点,访问的方法如下。首先,找到一段长度为k的连续的点,(比如编号为x, x+1, x+2...x+k-1),然后查看缓存中的点,有三种可能:某点在缓存中但这次不需要访问,则移出缓存;某点不在缓存中但这次要访问,访问该点并将它加入缓存;某点在缓存中且要访问,不访问该点但将其留在缓存中。要按顺序访问A[i]中的点,最少需要进行多少次访问操作。

  n <= 10^9, k <= n, A.size() <= 50。

  注意,如果A[] = {2, 3, 10},k = 3,n = 1000则只需访问2, 3, 4, 8, 9, 10即可。

解法:本题的关键点在于要注意到一点,要访问A[i],最优解访问的连续k个点只有两类可能:A[j], A[j]+1...A[j]+k-1和A[j]-k+1, A[j]-k+2...A[j]。(*)

   所以,先预处理出可能从哪些点开始访问。然后,由于要按顺序访问A[i],所以只需要做一遍dp即可。

tag:dp, think

  1 // BEGIN CUT HERE
  2 /*
  3  * Author:  plum rain
  4  * score :
  5  */
  6 /*
  7 
  8  */
  9 // END CUT HERE
 10 #line 11 "ContiguousCache.cpp"
 11 #include <sstream>
 12 #include <stdexcept>
 13 #include <functional>
 14 #include <iomanip>
 15 #include <numeric>
 16 #include <fstream>
 17 #include <cctype>
 18 #include <iostream>
 19 #include <cstdio>
 20 #include <vector>
 21 #include <cstring>
 22 #include <cmath>
 23 #include <algorithm>
 24 #include <cstdlib>
 25 #include <set>
 26 #include <queue>
 27 #include <bitset>
 28 #include <list>
 29 #include <string>
 30 #include <utility>
 31 #include <map>
 32 #include <ctime>
 33 #include <stack>
 34 
 35 using namespace std;
 36 
 37 #define clr0(x) memset(x, 0, sizeof(x))
 38 #define clr1(x) memset(x, -1, sizeof(x))
 39 #define pb push_back
 40 #define sz(v) ((int)(v).size())
 41 #define all(t) t.begin(),t.end()
 42 #define zero(x) (((x)>0?(x):-(x))<eps)
 43 #define out(x) cout<<#x<<":"<<(x)<<endl
 44 #define tst(a) cout<<a<<" "
 45 #define tst1(a) cout<<#a<<endl
 46 #define CINBEQUICKER std::ios::sync_with_stdio(false)
 47 
 48 typedef vector<int> vi;
 49 typedef vector<string> vs;
 50 typedef vector<double> vd;
 51 typedef pair<int, int> pii;
 52 typedef long long int64;
 53 
 54 const double eps = 1e-8;
 55 const double PI = atan(1.0)*4;
 56 const int inf = 2139062143 / 2;
 57 const int64 llinf = 1LL<<62;
 58 
 59 class ContiguousCache
 60 {
 61     public:
 62         int64 d[100][200];
 63 
 64         int64 over(int a, int b, int c, int d, int k)
 65         {
 66             if (d < a || c > b) return k;
 67             return max(b, d) - min(a, c) + 1 - k;
 68         }
 69 
 70         long long minimumReads(int len, int k, vector <int> pos){
 71             vi x;
 72             for (int i = 0; i < sz(pos); ++ i){
 73                 x.pb (min(pos[i], len-k));
 74                 x.pb (max(0, pos[i]-k+1));
 75             }
 76             x.erase(unique(x.begin(), x.end()), x.end());
 77 
 78             for (int i = 0; i < sz(pos); ++ i)
 79                 for (int j = 0; j < sz(x); ++ j) d[i][j] = llinf;
 80 
 81             for (int i = 0; i < sz(x); ++ i) if (x[i] <= pos[0] && x[i]+k-1 >= pos[0])
 82                 d[0][i] = k;
 83 
 84             for (int i = 1; i < sz(pos); ++ i)
 85                 for (int j = 0; j < sz(x); ++ j) if (x[j] <= pos[i] && x[j]+k-1 >= pos[i])
 86                     for (int t = 0; t < sz(x); ++ t) if (d[i-1][t] != llinf)
 87                         d[i][j] = min(d[i][j], d[i-1][t] + over(x[t], x[t]+k-1, x[j], x[j]+k-1, k));
 88 
 89             int64 ret = llinf;
 90             for (int i = 0; i < sz(x); ++ i) ret = min(ret, d[sz(pos)-1][i]);
 91             return ret;
 92         }
 93         
 94 // BEGIN CUT HERE
 95     public:
 96     void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); }
 97     private:
 98     template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '"' << *iter << "","; os << " }"; return os.str(); }
 99     void verify_case(int Case, const long long &Expected, const long long &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "	Expected: "" << Expected << '"' << endl; cerr << "	Received: "" << Received << '"' << endl; } }
100     void test_case_0() { int Arg0 = 100; int Arg1 = 3; int Arr2[] = {0, 2, 16, 13}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); long long Arg3 = 7LL; verify_case(0, Arg3, minimumReads(Arg0, Arg1, Arg2)); }
101     void test_case_1() { int Arg0 = 100; int Arg1 = 10; int Arr2[] = {1,10,19,28,30,37}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); long long Arg3 = 29LL; verify_case(1, Arg3, minimumReads(Arg0, Arg1, Arg2)); }
102     void test_case_2() { int Arg0 = 1000000000; int Arg1 = 500000000; int Arr2[] = {0, 999999999, 1, 500000000, 500000001, 987654321}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); long long Arg3 = 1987654320LL; verify_case(2, Arg3, minimumReads(Arg0, Arg1, Arg2)); }
103     void test_case_3() { int Arg0 = 8; int Arg1 = 2; int Arr2[] = {7}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); long long Arg3 = 2LL; verify_case(3, Arg3, minimumReads(Arg0, Arg1, Arg2)); }
104 
105 // END CUT HERE
106 
107 };
108 
109 // BEGIN CUT HERE
110 int main()
111 {
112 //    freopen( "a.out" , "w" , stdout );    
113     ContiguousCache ___test;
114     ___test.run_test(-1);
115        return 0;
116 }
117 // END CUT HERE
View Code

    

原文地址:https://www.cnblogs.com/plumrain/p/srm_410.html