【UVA1379】Pitcher Rotation (贪心+DP)

题意:

  你经营者一直棒球队。在接下来的g+10天中有g(3<=g<=200)场比赛,其中每天最多一场比赛。你已经分析出你的n(5<=n<=100)个投手中每个人对阵所有m个对手的胜率(一个n*m矩阵),要求给出作战计划(即每天使用哪个投手),使得总胜场数的期望值最大。注意,一个投手在上场一次后至少要休息4天。

分析:

  如果这题直接记录前4天中每天上场的投手编号1~n,时间和空间都无法承受。但是,不记录又不行。因为规定一个投手在上场一次后至少要休息4天,也就是说记录前4天的作战计划是必要的,但是我们可以简化这个编号的范围。在这里用到了贪心的思想,对于第i天,我们只会选择当天能力值前5的投手出战。所以记录的时候,只需记录你选的是当天排名第几的投手,然后判断选择不同于前4天的投手DP即可。

  感觉自己的贪心还是不够好啊~~

代码如下:(好多维,有点恶心,听说不用滚动会疯狂RE,然后我就滚动了。但还是不造为啥依然RE了好多遍TAT)

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<iostream>
 6 using namespace std;
 7 #define Maxn 110
 8 #define Maxm 40
 9 #define Maxg 250
10 #define Maxd 6
11 
12 int p[Maxg][Maxg],d[Maxg];
13 int f[2][Maxd][Maxd][Maxd][Maxd];
14 int b[Maxg][Maxg];
15 int n,m,g;
16 
17 struct node
18 {
19     int id,x;
20 }t[Maxg];
21 
22 bool cmp(node x,node y) {return x.x>y.x;}
23 
24 int mymax(int x,int y) {return x>y?x:y;}
25 
26 void init()
27 {
28     scanf("%d%d%d",&n,&m,&g);
29     for(int i=1;i<=m;i++)
30       for(int j=1;j<=n;j++)
31         scanf("%d",&p[i][j]);
32     for(int i=1;i<=g+10;i++) scanf("%d",&d[i]);
33     memset(b,0,sizeof(b));
34     for(int i=1;i<=m;i++)
35     {
36         for(int j=1;j<=n;j++) t[j].id=j,t[j].x=p[i][j];
37         sort(t+1,t+1+n,cmp);
38         for(int j=1;j<=5;j++) b[i][j]=t[j].id;
39     }
40 }
41 
42 void dp()
43 {
44     memset(f,-1,sizeof(f));
45     f[0][0][0][0][0]=0;
46     int np=0,ans=0;
47     int wj=-10,wk=-10,wl=-10,wq=-10; 
48      for(int i=1;i<=g+10;i++)
49      {
50        if(d[i]==0) continue;
51        ans=0;
52        memset(f[1-np],-1,sizeof(f[1-np]));
53        for(int j=0;j<=5;j++)
54         for(int k=0;k<=5;k++)
55          for(int l=0;l<=5;l++)
56           for(int q=0;q<=5;q++) if(f[np][j][k][l][q]!=-1)
57           {
58               for(int id=1;id<=5;id++) 
59               {
60                   int now=d[i];
61                   if((i-wj<=4&&b[now][id]==b[d[wj]][j])||(i-wk<=4&&b[now][id]==b[d[wk]][k])||
62                     (i-wl<=4&&b[now][id]==b[d[wl]][l])||(i-wq<=4&&b[now][id]==b[d[wq]][q]))  continue;
63                   f[1-np][k][l][q][id]=
64                     mymax(f[1-np][k][l][q][id],f[np][j][k][l][q]+p[now][b[now][id]]);
65                   ans=mymax(ans,f[1-np][k][l][q][id]);
66               }
67          }
68         wj=wk;wk=wl;wl=wq;wq=i;
69         np=1-np;
70      }
71       
72     printf("%.2lf
",ans*1.0/100);
73 }
74 
75 int main()
76 {
77     int T;
78     scanf("%d",&T);
79     while(T--)
80     {
81         init();
82         dp();
83     }
84     return 0;
85 }
uva1379

2016-03-06 15:42:06

原文地址:https://www.cnblogs.com/Konjakmoyu/p/5247629.html