状态压缩DP裸题,比赛的时候没反应过来,进行了n次枚举起点的solve,导致超时。
#include<cstdio> #include<iostream> #include<vector> #include<cstring> using namespace std; int n,m,k; int cost[20][20],val[20]; int a,b,c; long long dp[1<<19][20]; vector<int> hhh[19]; int judge(int x){ int res=0; while(x!=0){ if(x&1) res++; x>>=1; } return res; } void init(){ for(int i=0;i<(1<<18);i++) hhh[judge(i)].push_back(i); } long long solve(){ for(int s=0;s<(1<<n);s++) fill(dp[s],dp[s]+n,1); for(int i=0;i<n;i++) dp[1<<i][i]=-val[i]; for(int jj=1;jj<=n;jj++){ for(int jjj=0;jjj<hhh[jj].size();jjj++){ int j=hhh[jj][jjj]; for(int i=0;i<n;i++){ if(dp[j][i]==1||(j&(1<<i))==0) continue; int tt=((1<<n)-1)^(j); for(int k=0;k<n;k++) if((j&(1<<k))==0) dp[j|(1<<k)][k]=min(dp[j|(1<<k)][k],dp[j][i]+cost[i][k]-val[k]); } } } long long res=0; for(int j=0;j<=(1<<n)-1;j++){ if(judge(j)==m) for(int i=0;i<n;i++) res=min(res,dp[j][i]); } return res; } int main(){ scanf("%d%d%d",&n,&m,&k); init(); for(int i=1;i<=n;i++) scanf("%d",&val[i-1]); while(k--){ scanf("%d%d%d",&a,&b,&c); cost[a-1][b-1]=-c; } long long ans=100; printf("%lld",-solve()); return 0; }