【发布时间】:2015-07-16 08:53:03
【问题描述】:
您的任务是计算 n 的不同分配的数量 给 n 个学生提供不同的主题,这样每个人都能得到一个 他喜欢的话题。
每个测试用例以学生人数 n (1
我通过定义 DP[i][mask] 来表示仅使用 i 元素形成掩码集的方法的数量来解决这个问题!
这里的 mask 是 Subjects 的一个子集,它显示了有多少科目和哪些科目。
重复出现
for(i=1;i<N;i++) //Student
for(j=1;j<(1<<N);j++) //Subject Subset
{
for(k=0;k<N;k++) //Selecting subject
if( (j&(1<<k)) && A[i][k] )
DP[i][j]+=DP[i-1][j^(1<<k)];
}
即从第 i 个学生最喜欢的科目中取一门科目并递归到较低的州!
但是,这还不够,因为解决方案的复杂度为 O(2^N * N^2)。
我们至少需要降低一个 N!
如何降低这个问题的复杂性?这是我的代码:
#include<bits/stdc++.h>
using namespace std;
long long DP[20][(1<<20)+1];
int main()
{
int T;
scanf("%d",&T);
for(;T;--T)
{
int N,i,j,k;
scanf("%d",&N);
int A[N+1][N+1];
for(i=0;i<N;i++)
for(j=0;j<N;j++)
scanf("%d",&A[i][j]);
/*
First of all let's think about the state!!
DP[i][j] where i is the i th student I am considering j is a bitmask which tells me which all subjects are
Done!!
********All Right************
So what can the recurrence be..?
traverse over the array A[i][]
If We can use the k th element of i.e A[i][k].
We need to try assigning it and Get the number of ways
*********Seems Fine *********
What will be the base case??
When only one element left in the mask and i is 1 we won't traverse more down!!
**OK**
SO what is the topological order of DP states !>>>????
I dont Know!! Let's think... Let me explain ummmmmmmmmmmmmmmmmmmmmmmmmmmm
ummmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
I am like calling a smaller i with smaller subset!
for every i
go in the order of increasing subsets
I think that should work!! Let's see
*/
for(i=0;i<(1<<N);i++)
DP[0][i]=0;
for(i=0;i<N;i++)
if(A[0][i])
DP[0][1<<i]=1;
for(i=1;i<N;i++) //Student
for(j=1;j<(1<<N);j++) //Subject Subset
{
DP[i][j]=0;
for(k=0;k<N;k++) //Selecting subject
if( (j&(1<<k)) && A[i][k] )
DP[i][j]+=DP[i-1][j^(1<<k)];
}
long long ans=0;
for(i=1;i<(1<<N);i++)
ans+=DP[N-1][i];
printf("%lld\n",ans);
}
return 0;
}
问题链接以备不时之需:Spoj
【问题讨论】:
标签: c++ algorithm optimization dynamic-programming