「CTSC 2011」幸福路径

[「CTSC 2011」幸福路径

蚂蚁是可以无限走下去的,但是题目对于精度是有限定的,只要满足精度就行了.

({(1-1e-6)}^{2^{25}}=2.6e-15)

考虑使用倍增的思想.

定义(dp[x][y][t])为从(x)点出发,走(2^t)步,到达(y)所得到的最大权值.

dp转移:(dp[x][y][t]=max(dp[x][k][t-1]+p^{2^{t-1}} dp[k][y][t-1]))(k subset [1,n])).

一次转移复杂度为(o(n^3)).

总复杂度(o(n^3*K)),(K leq 25).

#include<bits/stdc++.h>
#define rep(q,a,b) for(int q=a,q##_end_=b;q<=q##_end_;++q)
#define dep(q,a,b) for(int q=a,q##_end_=b;q>=q##_end_;--q)
#define mem(a,b) memset(a,b,sizeof a )
#define debug(a) cerr<<#a<<' '<<a<<"___"<<endl
using namespace std;
void in(int &r) {
	static char c;
	r=0;
	while(c=getchar(),!isdigit(c));
	do r=(r<<1)+(r<<3)+(c^48);
	while(c=getchar(),isdigit(c));
}
bool cur1;
const int mn=105;
const int mm=1005;
int n,m,cnt1,s;
double lp,p;
double val[mn],dp[mn][mn][2];
bool cur2;
int main() {
//	cerr<<(&cur1-&cur2)/1024.0/1024<<endl;
	freopen("path.in","r",stdin);
	freopen("path.out","w",stdout);
	int st;
	scanf("%d%d",&n,&m);
	rep(q,1,n)scanf("%lf",&val[q]);
	scanf("%d%lf",&st,&p);
	int a,b;
	bool ok=1;
	rep(q,1,n)rep(w,1,n)dp[q][w][ok]=-1e9;
	rep(q,1,n)dp[q][q][ok]=0;
	double Mx=0;
	rep(q,1,m) {
		scanf("%d%d",&a,&b);
		dp[a][b][ok]=val[b]*p;
		Mx=max(Mx,dp[a][b][ok]);
	}
	for(int tim=1;tim<=25;++tim){
		if(p*Mx<1e-3)break;
		ok=!ok;
		rep(q,1,n)rep(w,1,n)dp[q][w][ok]=-1e9;
		rep(q,1,n)dp[q][q][ok]=0;
		rep(k,1,n)rep(q,1,n)rep(w,1,n)dp[q][w][ok]=max(dp[q][w][ok],dp[q][k][!ok]+dp[k][w][!ok]*p);
		rep(q,1,n)rep(w,1,n)Mx=max(Mx,dp[q][w][ok]);
		p*=p;
	}
	double ans=0;
	rep(q,1,n)ans=max(ans,dp[st][q][ok]);
	printf("%.1lf
",val[st]+ans);
	return 0;
}
原文地址:https://www.cnblogs.com/klauralee/p/11283667.html