爬山

震惊!dp还能这样用

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn=55, maxm=305, INF=0x3f3f3f3f;
int n, m;
struct Edge{
    int to, nxt, v;
}e[maxm*2];
int cnte, fir[maxn];
void addedge(int x, int y, int z){
    Edge &ed=e[++cnte]; ed.v=z;
    ed.to=y; ed.nxt=fir[x]; fir[x]=cnte; }
int f[maxn][25][maxn*maxn];
int sqr(int x){ return x*x; }
inline void up_min(int &x, int y){ if (x>=y) x=y; }

int in[maxn], q[maxn], hd, tl;
void topo(){
    for (int i=1; i<=n; ++i) if (!in[i]) q[tl++]=i;
    while (hd<tl){
        int u=q[hd++];
        for (int i=fir[u]; i; i=e[i].nxt){
            int v=e[i].to; --in[v];
            for (int j=0; j<20; ++j)
                for (int k=0; k<2500; ++k)
                    up_min(f[v][j+1][k+e[i].v], f[u][j][k]+sqr(e[i].v));
            if (in[v]==0) q[tl++]=v;
        }
    }
}

int main(){
    scanf("%d %d", &n, &m); int x, y, z;
    for (int i=1; i<=m; ++i){
        scanf("%d%d%d", &x, &y, &z); ++in[y];
        addedge(x, y, z); }
    memset(f, 0x3f, sizeof(f));
    f[1][0][0]=0; topo(); double ans=INF;
    for (int j=1; j<20; ++j)
        for (int k=0; k<2500; ++k)
            ans=min(ans, (double)(1ll*j*f[n][j][k]-sqr(k))/(j*j));
    printf("%.4lf\n", ans);
    return 0;
}
posted @ 2018-10-10 16:14 pechpo 阅读(...) 评论(...) 编辑 收藏