SRM 586 DIV1

A

  考虑都是格点 , 枚举所有y+-0.5就行了.

  trick是避免正好在y上的点重复统计.

 1 class PiecewiseLinearFunction {

 2 public:

 3     int maximumSolutions(vector <int>);

 4 };

 5 int n;

 6 int cross(vector<int> Y,double y) {

 7     int res=0;

 8     double l,r;

 9     l = (double)Y[0];

10     r = (double)Y[1];

11     for (int i=1 ; i<n ; i++ ) {

12         if (y>l && r>l && y<r) res++;

13         else if (y<l && r<l && y>r) res++;

14         l = r;

15         if (i+1<n) r = Y[i+1];

16     }

17     for (int i=0 ; i<n ; i++ ) if (fabs(Y[i]-y)<1e-6) res++;

18     return res;

19 }

20 

21 int solv(vector<int> Y) {

22     for (int i=1 ; i<n ; i++ ) if (Y[i]==Y[i-1]) return -1;

23     if (Y.size()==1) return 1;

24     int res = 1;

25     for (int i=0 ; i<n ; i++ ) {

26         int tmp = cross(Y,Y[i]);

27         res = max(res,tmp);

28         

29         tmp = cross(Y,Y[i]+0.5);

30         res = max(res,tmp);

31         

32         tmp = cross(Y,Y[i]-0.5);

33         res = max(res,tmp);

34         printf("y:%d tmp:%d\n",Y[i],tmp);

35     }

36     return res;

37 }

38 

39 int PiecewiseLinearFunction::maximumSolutions(vector <int> Y) {

40     n = Y.size();

41     int ans = solv(Y);

42     return ans;

43 }
View Code

 

B

  差分约束模型,每一条历史记录可以转化成一条约束,然后建边求最短路.

  a->b的最短路和b->a的最短路可以确定一个区间[l,r]  如果l>r则该区间不存在,

  判断是否可能时 , 检查线段是否有交点.

  

 1 using namespace std;

 2 #define maxn 100

 3 #define INF 1000000000

 4 vector<int> his[maxn];

 5 int n,f[maxn][maxn];

 6 class History {

 7 public:

 8     string verifyClaims(vector <string>, vector <string>, vector <string>);

 9 };

10 

11 void addedge(int a,int ida,int b,int idb) {

12     int sa = his[a][ida] , ta = his[a][ida+1]-1;

13     int sb = his[b][idb] , tb = his[b][idb+1]-1;

14     int b_a = ta-sb;

15     int a_b = tb-sa;

16     f[b][a] = min(f[b][a],b_a);

17     f[a][b] = min(f[a][b],a_b);

18 }

19 

20 void floyd() {

21     for (int k=0 ; k<n ; k++ )

22         for (int i=0 ; i<n ; i++ )

23             for (int j=0 ; j<n ; j++ )

24                 f[i][j] = min(f[i][j] , f[i][k]+f[k][j]);

25 }

26 

27 void pretreat(vector<string> dyn , vector<string> war) {

28     n = dyn.size();

29     for (int i=0 ; i<n ; i++ ) {

30         stringstream ss(dyn[i]);

31         int num;

32         while (ss>>num) his[i].push_back(num);

33     }

34 

35     for (int i=0 ; i<n ; i++ ) 

36         for (int j=0 ; j<n ; j++ ) f[i][j] = INF;

37 

38     string s="";

39     for (int i=0 ; i<(int)war.size() ; i++ ) s += war[i];

40     stringstream ss(s);

41     string t;

42     while (ss>>t) {

43         char a,b;

44         int ida,idb;

45         sscanf(t.c_str(),"%c%d-%c%d",&a,&ida,&b,&idb);

46         addedge(a-'A',ida,b-'A',idb);

47     }

48     floyd();

49 }

50 

51 char check(int a,int ida,int b,int idb) {

52     int sa = his[a][ida] , ta = his[a][ida+1]-1;

53     int sb = his[b][idb] , tb = his[b][idb+1]-1;

54     int r = ta-sb;

55     int l = sa-tb;

56     int R = f[b][a];

57     int L = -f[a][b];

58     if (l>R || r<L) return 'N';

59     return 'Y';

60 }

61 

62 string History::verifyClaims(vector <string> dyn, vector <string> war, vector <string> query) {

63     pretreat(dyn,war);

64     string res="";

65     for (int i=0 ; i<(int)query.size() ; i++ ) {

66         string t = query[i];

67         char a,b;

68         int ida,idb;

69         sscanf(t.c_str(), "%c%d-%c%d",&a,&ida,&b,&idb);

70         res += check(a-'A',ida,b-'A',idb);

71     }

72     return res;

73 }
View Code

 

C

  首先找出light string的性质:

    1. 字符集 = min(26,长度);

    2. 相同字母连续出现;

  然后发现可以用L,R来表示 从所有串看来,某字母的使用区间 , 第一次使用是L,

  最后一次使用是R , 然后就是找到一些约束条件和相关变量,枚举变量dp ,利用约束条件优化复杂度...

  

 1 int f[maxn][30][30] , len[maxn] , n;

 2 

 3 int dfs(int i,int a,int o,vector<int> L) {

 4     int & res = f[i][a][o];

 5     

 6     if (res == -1){

 7         res = INF;

 8         if (i==n) {

 9             if (o==0) {

10                 res = 0;

11             }

12         } else {

13             int s = i-1>=0?len[i-1]:0;

14             int m = min(L[i],26);

15             for (int c=0 ; c<=m && c<=o ; c++ ) {

16                 for (int p=0 ; c+p<=m && p<=a ; p++ ) {

17                     for (int u=0 ; p+u+c<=m && u+c<=o ; u++ ) {

18                         int k = m-(c+u+p);

19                         if (p+k>a) continue;

20                         int w = dfs(i+1,a-k-p,o-c+p,L);

21                         if (u > 0 ) {                

22                             w += s*c + (c-1)*c/2;

23                             w -= (s+L[i]-1)*p - (p-1)*p/2;

24                         } else {            

25                             w += s*c + (c-1)*c/2;

26                             w -= (s+L[i]-1)*p - (p-1)*p/2;

27                             w += L[i]-(c+p+k);

28                         }

29                         res = min(res,w);

30                     }

31                 }

32             }

33         }

34     }

35     return f[i][a][o] = res;

36 }

37 

38 int StringWeight::getMinimum(vector <int> L) {

39     n = L.size();

40     memset(f, -1, sizeof(f));

41     for (int i=0 ; i<n ; i++ ) len[i] = i==0?L[i]:len[i-1]+L[i];

42     int ans = dfs(0,26,0,L);

43     return ans;

44 }
View Code

 

  

你可能感兴趣的:(div)