251 条题解
-
0
gujoe LV 3 @ 18 年前
又是双重动归吗,为什么小胖办证那么少的人过
-
018 年前@
对啊,可以用Floyd算法!
——谁叫我不会DP呢,只好用o(n^3)的算法了。 -
019 年前@
郁闷啊,正确率直线下降....除了要注意走的方式以外,还要注意每一层的走法。
最下面一层只能从第一个出发...别的层就不一定了,所以要双重DP,超时了...
精简代码,去掉min函数,虽然写起来麻烦点,不过...过了!
PS:要是pascal有宏定义就好了 -
019 年前@
嵌套DP(至少我这么AC的)
注意转移的表达 -
-15 年前@
-
-17 年前@
-
-18 年前@
最短路……
-
-19 年前@
最短路+1
难点是构图,需要进行一些坑爹的代数运算,还要把点权移到边权上去。由于没有负权回路,故最短路总能输出答案。#include <stdio.h>
#include <limits.h>struct edge{
int to, value;
} E[600000][4];
int numEdge[600000];
int queue[1000000];
int dist[600000];
short using[600000];void addEdge(int from, int to, int value){
E[from][numEdge[from]].to = to;
E[from][numEdge[from]].value = value;
numEdge[from]++;
}
int minPath(int source, int sink, int numV){
int head = 0, tail = 1, i, u;
for(i=0; i<=numV; i++){
dist[i] = LONG_MAX;
using[i] = 0;
}
queue[0] = source;
dist[source] = 0;
using[source] = 1;
while(head < tail){
u = queue[head];
using[u] = 0;
for(i=0; i<numEdge[u]; i++){
if(dist[u] + E[u][i].value < dist[E[u][i].to]){
dist[E[u][i].to] = dist[u] + E[u][i].value;
if(!using[E[u][i].to]){
using[E[u][i].to] = 1;
queue[tail] = E[u][i].to;
tail++;
}
}
}
head++;
}
return dist[sink];
}
int main(){
int height, i, j, value, numV;
scanf("%d", &height);
for(i=0; i<600000; i++)
numEdge[i] = 0;
numV = 0;
for(i=1; i<=height; i++){
for(j=0; j<i; j++){
scanf("%d", &value);
addEdge(numV+j, numV+(j+i-1)%i, value); //left
addEdge(numV+j, numV+(j+i+1)%i, value); //right
if(i > 1){
addEdge(numV+j, numV-i+1+(j+i-2)%(i-1), value); //left-up
addEdge(numV+j, numV-i+1+(j+i-1)%(i-1), value); //right-up
}else{
addEdge(numV+j, height*(height+1)/2, value); //top
}
}
numV += i;
}
printf("%d\n", minPath(numV-height, height*(height+1)/2, numV+1));
return 0;
} -
-19 年前@
###Block code
最短路秒杀~!~!~!~!~!~! -
-110 年前@
-
-112 年前@