[关闭]
@01010101 2018-11-06T12:19:49.000000Z 字数 1365 阅读 936

noip2017

noip


DAY1T1小凯的疑惑

我是往余数上考虑的。考虑怎样凑出余数1.

DAY1T2时间复杂度

模拟,关键是不能漏情况。

DAY1T3

DAY2T1

DAY2T2宝藏

非常好的一道状压。与图的结合更是大大增加了题的难度。首先可以发现挖的路一定构成树,然后系数K就是把免费屋当成深度为0的根的树的深度。于是就需要一层一层的转移。预处理几个辅助数组。
注意INF的值,不然会爆。dp[i][s]表示当前在第i层,经过的点的集合是s的最小花费。
https://blog.csdn.net/phantomagony/article/details/78702573

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #define ll long long
  5. using namespace std;
  6. const int N=13;
  7. const int M=(1<<12)+10;
  8. const ll inf=0x3f3f3f3f;
  9. ll n,m,a,b,c,ans=1e15;
  10. ll g[N][N],init[N][M],cover[M][M],dp[N][M];
  11. int main(){
  12. // freopen("a.txt","r",stdin);
  13. memset(g,inf,sizeof(g));
  14. memset(init,inf,sizeof(init));
  15. memset(cover,inf,sizeof(cover));
  16. scanf("%lld%lld",&n,&m);
  17. for(int i=0;i<n;++i) g[i][i]=0;
  18. for(int i=1;i<=m;++i){
  19. scanf("%lld%lld%lld",&a,&b,&c);
  20. a--;b--;
  21. g[a][b]=min(g[a][b],c);
  22. g[b][a]=min(g[b][a],c);
  23. }
  24. ll t=(1<<n)-1;
  25. for(int i=0;i<n;++i)
  26. for(int j=0;j<=t;++j)
  27. // if((j&(1<<i))==0)
  28. for(int k=0;k<n;++k)
  29. if(j&(1<<k))
  30. init[i][j]=min(init[i][j],g[i][k]);
  31. for(int i=0;i<=t;++i){
  32. int C=i^t;//
  33. for(int s=C;s;s=(s-1)&C){
  34. ll tmp=0;
  35. for(int j=0;j<n;++j)
  36. if(s&(1<<j))
  37. tmp+=init[j][i];
  38. if(tmp<inf) cover[s][i]=min(cover[s][i],tmp);
  39. }
  40. }
  41. for(int i=0;i<n;++i){
  42. memset(dp,inf,sizeof(dp));
  43. dp[0][(1<<i)]=0;
  44. for(int j=1;j<n;++j)
  45. for(int ss=1;ss<=t;++ss){
  46. if(dp[j-1][ss]>=inf) continue;
  47. int C=ss^t;
  48. for(int s=C;s;s=(s-1)&C)
  49. dp[j][s|ss]=min(dp[j][s|ss],dp[j-1][ss]+j*cover[s][ss]);
  50. }
  51. for(int j=0;j<n;++j) ans=min(ans,dp[j][t]);
  52. }
  53. printf("%lld\n",ans);
  54. return 0;
  55. }

DAY2T3

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注