这个dp 也经常见的。 只不过自己想错了。 对于一个状态 有两种决策。 是否换队。 自己以为对于 10000个敌人。
会有2^10000 的选择。 肯定会超时。 但是事实不是这样的。 dp【i】【j】 这是队伍 i 对于 敌人 j 的时候的概率。 那么 i最大 120(最多120个队伍) j最大为10000
那么 最大的可能搜索 120*10000次(记忆化搜索) 就不会超时了。 这还是自己 对记忆化理解的不深吧
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <fstream>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <vector>
#include <cmath>
#include <iomanip>
typedef long long LL;
typedef unsigned long long LLU;
const double PI=acos(-1.0);
using namespace std;
#define MAXN 10000+10
#define INF 1<<30
int vis[125][MAXN] = {0};
double d[125][MAXN];
double mat[200][200];
int tar[MAXN];
int m,n;
double dp(int i, int j){
if(j == m-1 || i >= n || i < 0)
return 1;
if(vis[i][j])
return d[i][j];
vis[i][j] = 1;
d[i][j] = max(dp(i,j+1)*mat[i][tar[j+1]], dp(tar[j],j+1)*mat[tar[j]][tar[j+1]]);
return d[i][j];
}
int main (){
int r[20] = {0,0,0,1,4,10,20,35,56,84,120};
while(scanf("%d",&n) != EOF){
n = r[n];
memset(vis,0,sizeof(vis));
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
scanf("%lf",&mat[i][j]);
scanf("%d",&m);
for(int i = 0; i < m; i++)
scanf("%d",&tar[i]);
double ans = -1;
for(int i = 0; i < n; i++){
ans = max(ans, dp(i, 0)*mat[i][tar[0]]);
}
printf("%lf\n",ans);
}
return 0;
}