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

DIV1 250pt

题意:每个员工可以有几个直系上司,也可以有几个直系下属。没有直系下属的人工资为1,有直系下属的人工资为所有直系下属工资之和。求所有人工资之和。人数 <= 50。

解法:直接dfs一遍求出所有人工资就好。(官方题解说该问题满足拓补序,用dfs做拓补序再求)

tag:dfs

  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 << "	Expected: "" << Expected << '"' << endl; cerr << "	Received: "" << 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
View Code

DIV1 500pt

题意:平面上有很多点,A和B轮流将点染色,A将点染为红色,B将点染为蓝色。染完所有颜色后最终的score为所有两端颜色不一样的边的长度和(一端为红色,一端为蓝色)。B想使score尽量小,A想使score尽量大,两人都采用最优策略,A先手,问最终score的为多少。点数 <= 12。

解法:这道题最关键的是注意到两点:1、最终score之和染色结果有关,和染色顺序有关;2、在忽略染色顺序的情况下,每个点只有三种状态,无色,红色,蓝色。O(12^3)的复杂度完全能接受。也就是说,只需要dfs加记忆化就好。

tag:dfs, memorization

  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 << "	Expected: "" << Expected << '"' << endl; cerr << "	Received: "" << 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
View Code
原文地址:https://www.cnblogs.com/plumrain/p/srm_407.html