SRM 407(1-250pt, 1-500pt)
DIV1 250pt
题意:每个员工可以有几个直系上司,也可以有几个直系下属。没有直系下属的人工资为1,有直系下属的人工资为所有直系下属工资之和。求所有人工资之和。人数 <= 50。
解法:直接dfs一遍求出所有人工资就好。(官方题解说该问题满足拓补序,用dfs做拓补序再求)
tag:dfs
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // BEGIN CUT HERE 2 /* 3 * Author: plum rain 4 * score : 5 */ 6 /* 7 8 */ 9 // END CUT HERE 10 #line 11 "CorporationSalary.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 vi pat[100]; 59 bool son[100]; 60 int64 an[100]; 61 62 void dfs (int x) 63 { 64 int64 &ret = an[x]; 65 if (ret) return; 66 67 int n = sz(pat[x]); 68 if (!n){ 69 an[x] = 1; return; 70 } 71 72 for (int i = 0; i < n; ++ i){ 73 dfs (pat[x][i]); 74 ret += an[pat[x][i]]; 75 } 76 } 77 78 class CorporationSalary 79 { 80 public: 81 long long totalSalary(vector <string> v){ 82 clr0 (an); clr0 (son); 83 int n = sz(v); 84 for (int i = 0; i < n; ++ i) 85 pat[i].clear(); 86 87 for (int i = 0; i < n; ++ i) 88 for (int j = 0; j < n; ++ j) 89 if (v[i][j] == 'Y') 90 pat[i].pb (j), son[j] = 1; 91 92 for (int i = 0; i < n; ++ i) 93 if (!son[i]) dfs (i); 94 int64 ans = 0; 95 for (int i = 0; i < n; ++ i) 96 ans += an[i]; 97 return ans; 98 } 99 100 // BEGIN CUT HERE 101 public: 102 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(); } 103 private: 104 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(); } 105 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 << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } } 106 void test_case_0() { string Arr0[] = {"N"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); long long Arg1 = 1LL; verify_case(0, Arg1, totalSalary(Arg0)); } 107 void test_case_1() { string Arr0[] = {"NNYN", 108 "NNYN", 109 "NNNN", 110 "NYYN"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); long long Arg1 = 5LL; verify_case(1, Arg1, totalSalary(Arg0)); } 111 void test_case_2() { string Arr0[] = {"NNNNNN", 112 "YNYNNY", 113 "YNNNNY", 114 "NNNNNN", 115 "YNYNNN", 116 "YNNYNN"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); long long Arg1 = 17LL; verify_case(2, Arg1, totalSalary(Arg0)); } 117 void test_case_3() { string Arr0[] = {"NYNNYN", 118 "NNNNNN", 119 "NNNNNN", 120 "NNYNNN", 121 "NNNNNN", 122 "NNNYYN"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); long long Arg1 = 8LL; verify_case(3, Arg1, totalSalary(Arg0)); } 123 void test_case_4() { string Arr0[] = {"NNNN", 124 "NNNN", 125 "NNNN", 126 "NNNN"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); long long Arg1 = 4LL; verify_case(4, Arg1, totalSalary(Arg0)); } 127 128 // END CUT HERE 129 130 }; 131 132 // BEGIN CUT HERE 133 int main() 134 { 135 // freopen( "a.out" , "w" , stdout ); 136 CorporationSalary ___test; 137 ___test.run_test(-1); 138 return 0; 139 } 140 // END CUT HERE
DIV1 500pt
题意:平面上有很多点,A和B轮流将点染色,A将点染为红色,B将点染为蓝色。染完所有颜色后最终的score为所有两端颜色不一样的边的长度和(一端为红色,一端为蓝色)。B想使score尽量小,A想使score尽量大,两人都采用最优策略,A先手,问最终score的为多少。点数 <= 12。
解法:这道题最关键的是注意到两点:1、最终score之和染色结果有关,和染色顺序有关;2、在忽略染色顺序的情况下,每个点只有三种状态,无色,红色,蓝色。O(12^3)的复杂度完全能接受。也就是说,只需要dfs加记忆化就好。
tag:dfs, memorization
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // BEGIN CUT HERE 2 /* 3 * Author: plum rain 4 * score : 5 */ 6 /* 7 8 */ 9 // END CUT HERE 10 #line 11 "PointsGame.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 int n; 59 bool flag[50]; 60 vi an, px, py; 61 map<vi, double> mp; 62 63 double gao(int x) 64 { 65 //out (x); 66 //for (int i = 0; i < n; ++ i) 67 //tst(i), out (an[i]); 68 if (mp.count(an)) return mp[an]; 69 70 if(x == n){ 71 double ret = 0; 72 for (int i = 0; i < n; ++ i) if (an[i] == 1) 73 for (int j = 0; j < n; ++ j) if (an[j] == 2) 74 ret += sqrt((px[i]-px[j])*(px[i]-px[j]) + (py[i]-py[j])*(py[i]-py[j]) + 0.0); 75 mp[an] = ret; 76 return ret; 77 } 78 79 double ret = x & 1 ? inf : 0; 80 for (int i = 0; i < n; ++ i) if (!an[i]){ 81 an[i] = (x & 1) + 1; 82 double tmp = gao(x + 1); 83 //out (tmp); 84 if (x & 1) ret = min(tmp, ret); 85 else ret = max(tmp, ret); 86 an[i] = 0; 87 } 88 mp[an] = ret; 89 return ret; 90 } 91 92 class PointsGame 93 { 94 public: 95 double gameValue(vector <int> PX, vector <int> PY){ 96 px = PX; py = PY; 97 n = sz(px); 98 for (int i = 0; i < n; ++ i) an.pb (0); 99 clr0 (flag); mp.clear(); 100 return gao(0); 101 } 102 103 // BEGIN CUT HERE 104 public: 105 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(); } 106 //void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0();} 107 private: 108 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(); } 109 void verify_case(int Case, const double &Expected, const double &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } } 110 void test_case_0() { int Arr0[] = {0,0}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0,1}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); double Arg2 = 1.0; verify_case(0, Arg2, gameValue(Arg0, Arg1)); } 111 void test_case_1() { int Arr0[] = {0,0,1,1}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0,5,0,5}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); double Arg2 = 12.198039027185569; verify_case(1, Arg2, gameValue(Arg0, Arg1)); } 112 void test_case_2() { int Arr0[] = {0,0,0,0}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0,1,5,6}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); double Arg2 = 12.0; verify_case(2, Arg2, gameValue(Arg0, Arg1)); } 113 void test_case_3() { int Arr0[] = {0,1,2,3}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0,0,0,0}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); double Arg2 = 6.0; verify_case(3, Arg2, gameValue(Arg0, Arg1)); } 114 115 // END CUT HERE 116 117 }; 118 119 // BEGIN CUT HERE 120 int main() 121 { 122 // freopen( "a.out" , "w" , stdout ); 123 PointsGame ___test; 124 ___test.run_test(-1); 125 return 0; 126 } 127 // END CUT HERE
------------------------------------------------------------------
现在的你,在干什么呢?
你是不是还记得,你说你想成为岩哥那样的人。
现在的你,在干什么呢?
你是不是还记得,你说你想成为岩哥那样的人。