您的位置:首页 > 其它

【JZOJ4806】打工

2016-10-06 19:46 162 查看

Description



Solution

比赛的时候以为是n log n的,所以就没有去想n2,然后就花了好几个小时来推递推式,结果没有推出来。结果只让我拿了十分,去死吧,魔王大人。

其实,正解就是n方的。

设f[i][j]表示做到第i个,然后前面最大的是j。

f[i][j]=f[i−1][j]∗j+f[i−1][j−1]

因为每个i有a[i]的限制,所以每次f[i][da]+=a[i]−1(da表示前i个最大的a[i]),没有初始化,因为要边做边限制。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int maxn=10007,mo=1000007;
ll i,j,k,l,t,n,m,ans,da,u,v;
ll a[maxn],fact[maxn],ni[maxn],sum;
ll f[2][maxn];
int main(){
scanf("%lld",&n);
fo(i,1,n)scanf("%lld",&a[i]);
da=a[1];
fo(i,2,n){
u=v^1;
fo(j,1,i){
f[u][j]=(f[v][j]*j+f[v][j-1])%mo;
}
f[u][da]=(f[u][da]+a[i]-1)%mo;
da=max(da,a[i]);
v=u;
}
fo(i,1,n){
ans=(ans+f[v][i])%mo;
}
printf("%lld",ans+1);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: