【LibreOJ】6177 「美团 CodeM 初赛 Round B」送外卖2 状压DP

来源:互联网 发布:js 拖动事件 编辑:程序博客网 时间:2024/06/05 10:09

狂补状压DP

三进制

pow[]为基数


编号题目状态分数总时间内存代码 / 答案文件提交者提交时间#29229#6177. 「美团 CodeM 初赛 Round B」送外卖2 Accepted1001820 ms6092 KiBC++ / 1.7 KFMM2017-10-16 17:33:56



#include <cstdio>#include <algorithm>#include <cstring>#define C (c=nc())using namespace std;int s[15],t[15],l[15],r[15],f[25][59050],map[25][25],ans,n,m,q,u,o,e,pow[11],tmp;inline char nc(void){static char ch[100010],*p1=ch,*p2=ch;return p1==p2&&(p2=(p1=ch)+fread(ch,1,100010,stdin),p1==p2)?EOF:*p1++;}inline void read(int &n){static char c;int f=1;n=0;C;while (c<'0'||c>'9') c=='-'?f=-1,C:C;while (c>='0'&&c<='9') n=(n<<3)+(n<<1)+c-48,C;return (void)(n*=f);}int main(void){read(n),read(m),read(q);memset(map,0x3f,sizeof(map));memset(f,0x3f,sizeof(f));for (register int i=1;i<=m;++i){read(u),read(o),read(e);map[u][o]=min(map[u][o],e);}pow[0]=1;for (register int i=1;i<=n;++i) map[i][i]=0;for (register int k=1;k<=n;++k){for (register int i=1;i<=n;++i){for (register int j=1;j<=n;++j){map[i][j]=min(map[i][j],map[i][k]+map[k][j]);}}}for (register int i=1;i<=10;++i) pow[i]=3*pow[i-1];for (register int i=1;i<=n;++i) f[i][0]=map[1][i];for (register int i=1;i<=q;++i)read(s[i]),read(t[i]),read(l[i]),read(r[i]);for (int i=0;i<pow[q];++i)for (int j=1;j<=n;++j)for (int k=1;k<=q;++k){tmp=i%pow[k]/pow[k-1];if (tmp==0)f[s[k]][i+pow[k-1]]=min(f[s[k]][i+pow[k-1]],max(f[j][i]+map[j][s[k]],l[k]));elseif (tmp==1)if (f[j][i]+map[j][t[k]]<=r[k]) f[t[k]][i+pow[k-1]]=min(f[t[k]][i+pow[k-1]],f[j][i]+map[j][t[k]]);}for (int i=0;i<pow[q];++i){for (int j=1;j<=n;++j){if (f[j][i]!=1061109567){tmp=0;for (int k=1;k<=q;++k){if (i%pow[k]/pow[k-1]==2) ++tmp;}ans=max(ans,tmp);}}}printf("%d\n",ans);return 0;}




阅读全文
0 0