思路:状压dp,dp[i]表示上i中课程的最小学期,同时需要预处理每个i保存几个1,预处理每个课程的前缀课程。
class Solution {
public:
int minNumberOfSemesters(int n, vector<vector<int>>& dependencies, int k) {
vector<int> c((1<<15)+1,0);
for(int i=0;i<(1<<15);++i){
for(int j=0;j<n;j++){
if((i>>j)&1) ++c[i];//预处理每个数字含有多少1
}
}
vector<int> pre(17,0);//预处理前缀
for(int i=0;i<dependencies.size();++i){
pre[dependencies[i][1]-1]|=(1<<(dependencies[i][0]-1));
}
int dp[(1<<15)+10];
memset(dp,0x3f,sizeof(dp));
dp[0]=0;
for(int i=0;i<(1<<n);++i)
{
int temp=0;
for(int j=0;j<n;++j){
if((i&(1<<j))==0&&((pre[j]&i)==pre[j])) temp|=1<<j;
}
if(c[temp]<=k){
dp[i|temp]=min(dp[i|temp],dp[i]+1);
}
else
{
for(int j=temp;j;j=(j-1)&temp){
if(c[j]==k){
dp[i|j]=min(dp[i|j],dp[i]+1);
}
}
}
}
return dp[(1<<n)-1];
}
};