bzoj4145 AMPPZ2014 The Prices 状压dp

这个题.......很可以,很小清晰......
反正正经的东西我都没想到:
重点在于——————我不会处理那个多出来的路费
所以当时我就骚骚的弄了一颗树包状压
其实这是一个类01背包的状压
在每个状态用01背包求基于当前状态和当前费用的最优解最后再与之前最优解比较得最优解(记得这
个时候算上路费)
这样一直滚到最后就是最优解了
蒟蒻....

#include<cstdio>
using namespace std;
int d[105],c[105][20],n,m,tool[20],full,f[1<<16][102];
inline int Min(int x,int y)
{
    return x<y?x:y;
}
void init()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
      scanf("%d",&d[i]);
      for(int j=1;j<=m;j++)
       scanf("%d",&c[i][j]);
    }
    tool[1]=1;
    for(int i=2;i<=m;i++)tool[i]=tool[i-1]<<1;
    full=(1<<m)-1;
    for(int j=1;j<=full;j++)
    {
     f[j][1]=d[1];
     for(int k=1;k<=m;k++)
      if(tool[k]&j)
       f[j][1]+=c[1][k]; 
     f[j][2]=f[j][1];
    } 
}
void work()
{
     for(int i=2;i<=n;i++)
     {
      for(int j=0;j<=full;j++)
      {
        for(int k=1;k<=m;k++)
         if((tool[k]&j)==0)
          if(f[j|tool[k]][i]>f[j][i]+c[i][k])
           f[j|tool[k]][i]=f[j][i]+c[i][k];
        f[j][i]=f[j][i+1]=Min(f[j][i]+d[i],f[j][i-1]);
      }
     }
     printf("%d
",f[full][n]);
}
int main()
{
    init();
    work();
    return 0;
}
苟利国家生死以, 岂因祸福避趋之。
原文地址:https://www.cnblogs.com/TSHugh/p/6986351.html