题目:click
貌似不能交啊。逆推期望,dp[x]=(dp[x+1]+dp[x+2]+…+dp[x+6])/6+1,n个方程n个未知数,dp[u]==dp[v](u , v可以转换的时候),当x+i>n时,dp[x+i]并不能转移到dp[x],x的系数自减1,次数仍然计算,右侧常数6不变,高斯消元去解。
最后不知道为什么要强制转换为double才有答案。(能交的时候在交一发)
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 50005*4
using namespace std;
typedef long long ll;
const int MAXN=262144 * 2+ 10;
const double PI=acos(-1.0);
const long double eps=1e-14;
long double a[310][310];
int f[310];
int main()
{
memset(a,0,sizeof(a));
memset(f,0,sizeof(f));
int n,m,i,j;
scanf("%d %d",&n,&m);
for(i=1;i<=m;i++)
{
int x,y;
scanf("%d %d",&x,&y);
f[x]=y;
}
for(i=1;i<n;i++)
{
a[i][i]=6.0;
if(f[i])
{
a[i][f[i]]=-6.0;
a[i][n+1]=0;
continue;
}
a[i][n+1]=6.0;
for(j=1;j<=6;j++)
{
if(i+j<=n)
{
a[i][i+j]=-1.0;
}
else
{
a[i][i]-=1.0;
}
}
}
a[n][n]=1.0;
a[n][n+1]=0.0;
for(i=1;i<n;i++)//矩阵计算
{
int temp=i;
for(j=i+1;j<=n;j++)
{
if(fabs(a[j][i])>eps)
{
temp=j;
}
}
if(fabs(a[temp][i])>eps)
{
for(j=1;j<=n+1;j++)
swap(a[i][j],a[temp][j]);
for(j=i+1;j<=n;j++)
{
if(fabs(a[j][i])>eps)
{
long double tmp=a[j][i]/a[i][i];
for(int k=i;k<=n+1;k++)
{
a[j][k]-=tmp*a[i][k];
}
}
}
}
}
for(i=n;i>=1;i--)//回代结果
{
for(j=i+1;j<=n;j++)
{
if(fabs(a[i][j])>eps)
{
a[i][n+1]-=a[i][j]*a[j][n+1];
}
}
if(abs(a[i][i])<=eps&&abs(a[i][n+1])>eps)//方程左式子为0 右式大于0的情况无解题目说了存在
{
printf("-1\n");
return 0;
}
a[i][n+1]/=a[i][i];
}
printf("%.12lf",(double)a[1][n+1]);
return 0;
}