思路:从最后一个题开始做起,最后做第一道题,状态只要保证n个人一循环就可以了
递推公式:dp[id][s]=max(dp[id][s],dp[id+1][s|(1<<i)] + p[i][id]);
#include<stdio.h>
#include<string>
int T;
int n,m;
double p[15][1005];
bool vis[1010][1<<10];
double dp[1005][1<<10];
double max(double a,double b) {
if (a>b) return a;
else return b;
}
double Solved(int i,int s) {
int j;
if (s==(1<<n)-1) s=0;
if (dp[i][s]>0) return dp[i][s];//记忆化搜索
if(i==m)return dp[i][s];
for(j=0;j<n;j++) {
if (s&(1<<j)) continue;//第k个人是否比过了
dp[i][s]=max(dp[i][s], Solved(i+1,s|(1<<j))+p[j][i] );
}
//printf("dp[%d][%d]: %lf\n",i,s,dp[i][s]);
return dp[i][s];
}
int main() {
//freopen("in.txt","r",stdin);
scanf("%d",&T);
int i,j,k;
int cas=1;
while(T--) {
scanf("%d%d",&n,&m);
for(i=0;i<n;i++) {
for(j=0;j<m;j++) {
scanf("%lf",&p[i][j]);
}
}
memset(dp,0,sizeof(dp));
memset(vis,false,sizeof(vis));
printf("Case #%d: %.5lf\n",cas++,Solved(0,0));
}
return 0;
}