51nod 1850 카드 추첨 대회(12성 연합 시험 모형 테스트) ["동적"(다항식)DP]
제목 분석:
만약에 i번째 개인의 수입만 요구한다면 그가 선택한 카드를 열거한 다음에 O(n2)DP가 그의 순위가 k일 확률을 계산하면 된다.한 사람을 구하는 것은 O(n3)이고, n사람을 구하는 것은 O(n4)이다.이 폭력을 휘두르고 보니 63점이나 돼서 도망갔어요.
O(n3)의 방법: 하나의 권한 A에 대해 분명히 그 값보다 큰 값만 순위에 영향을 미친다.그래서 우리는 모든 A값을 함께 정렬하고 Ai의 기대 순위를 어떻게 구하는지 고려한다.만약에 서로 다른 A를 다른 사람이 선택한다면 이것은 매우 쉬운DP이다. 그러나 현재Ai의 앞에는Aj가 같은 사람의 선택일 수 있다. 이것은 비교적 까다롭다. 우리는 앞의 공헌을 제거해야 한다.
만약에 값 A가 n 개인 중의 기대 순위를 하나의 생성 함수로 간주한다면 A보다 큰 수는 A의 순위를 증가시킬 수 있다.i pi는 i번째 개인의 선택이 A보다 클 확률로 F(x) = ∏i = 1 n(p i x +(1 - 6 p i) F (x) =\prod{i=1}^n\large(p_ix+(1-p_i)\large) F(x)=i=1∏n(pix+(1−pi))
제i개인의 선택Ai가 그의 수익에 기여한 바를 통계하려면 이때의 다항식을 제i개인의 식을 제외하면 Ai가 다른 n-1명에 대한 기대 순위를 얻을 수 있다. Ai를 선택할 확률을 타고 대가를 제외하고 ans[i]에 추가하면 된다.(이곳에서 i의 다항식을 제외하면 위의 문제를 완벽하게 해결할 수 있다)
권한 값이 변동할 때 F(x) F(x) F(x)는 한 항목만 변동할 수 있고 변동된 항목은 모두 한 항목이므로 O(n)에서 한 번의 제법과 곱셈을 할 수 있다.(사실 이곳은 DP와 유사하다)
구체적으로 코드를 쓸 때 다항식을 n-1항에 유지하고 Ai의 공헌을 구할 때 i의 다항식을 제거하고 i-1의 다항식을 곱할 수 있다.
Code:
#include
#include
#include
#define LL long long
#define maxn 205
using namespace std;
const int mod = 1e9+7;
inline int ksm(int a,int b){
int s=1;
for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) s=1ll*s*a%mod;
return s;
}
const int inv100 = ksm(100,mod-2);
int n,m[maxn],cnt,v[maxn];
int ans[maxn],ps[maxn];
struct node{
int A,G,P,id;
bool operator < (const node &t)const{return A>t.A;}
}a[maxn*maxn];
int f[maxn];
void Div(int p){
int inv=ksm(1-p,mod-2);//
for(int i=0;i<n;i++) f[i]=(f[i]-1ll*f[i-1]*p%mod)*inv%mod;
}
void Mul(int p){
for(int i=n-1;i>=0;i--) f[i]=(1ll*f[i]*(1-p)+1ll*f[i-1]*p)%mod;
}
int main()
{
//freopen("H.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&m[i]);
int s=0;
for(int j=1;j<=m[i];j++){
a[++cnt].id=i;
scanf("%d%d%d",&a[cnt].A,&a[cnt].G,&a[cnt].P);
a[cnt].G=1ll*(100-a[cnt].G)*inv100%mod;
s+=a[cnt].P;
}
for(int j=0;j<m[i];j++) a[cnt-j].P=1ll*a[cnt-j].P*ksm(s,mod-2)%mod;
}
for(int i=0;i<n;i++) scanf("%d",&v[i]);
sort(a+1,a+1+cnt);
f[0]=1;
for(int i=1;i<=cnt;i++){
if(a[i].id!=a[i-1].id){
Div(ps[a[i].id]);//
Mul(ps[a[i-1].id]);
}
for(int j=0;j<n;j++)
ans[a[i].id]=(ans[a[i].id]+1ll*f[j]*v[j]%mod*a[i].P%mod*a[i].G)%mod;
ps[a[i].id]=(ps[a[i].id]+a[i].P)%mod;
}
for(int i=1;i<=n;i++) printf("%d
",(ans[i]+mod)%mod);
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
leetcode 기예음란-귀속 중도 강제 탈출문서 목록 앞말 강제 탈출에 관하여 전언 우리는 귀속 프로그램의 많은 특징을 알고 있다. 예를 들어 가독성이 좋고 코드가 간결하지만 단점도 뚜렷하다. 귀속 시간의 복잡도가 비교적 높기 때문에 비망록 귀속 알고리즘으로...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.