题意:
你经营者一直棒球队。在接下来的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)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
2016-03-06 15:42:06