洛谷P4802 [CCO 2015]路短最
题目
https://www.luogu.com.cn/problem/P4802
思路
数据范围 ,义眼丁真,鉴定为状压。
好,那我们来思考一下状态的构建。其实是很套路的东西,我们用 表示当前在 点,已经走过的点的集合为 的答案。
然后写个记搜就完了。
比较有意思的一点是最长路的终点是钦定好的,我第一次做的时候没考虑这个WA了一大片。比较好想的一个想法是搜的时候判一下如果当前点没有出边且不等于n-1的时候返回-inf。
但是这个写法感觉比较丑。
我想了一个自认为比较妙的处理方法:建图的时候加一条从n-1到新点n的单向边,长度为1000000(或者任意一个很大的数)。这样就基本不用改之前的记搜代码了。
最终的ans减去这个大数就是答案。因为这条大边在dp时是必定选到的,所以就保证了走到n-1点。
不得不说还是切水题比较快乐,Ynoi毒瘤,lxl毒瘤
代码
点击查看代码
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int fst[20],nxt[500],to[500],w[500],cnt=0;
int n,m;
int dp[20][1<<18];
void add(int x,int y,int z){
to[++cnt]=y;
w[cnt]=z;
nxt[cnt]=fst[x];
fst[x]=cnt;
}
int dfs(int x,int st){
int i;
if(dp[x][st]) return dp[x][st];
if(x==n) return 0;
for(i=fst[x];i;i=nxt[i]){
if(st&(1<<to[i])) continue;
dp[x][st]=max(dp[x][st],w[i]+dfs(to[i],st|1<<x));
}
return dp[x][st];
}
int main(){
int i,j;
int x,y,z;
int ans;
scanf("%d%d",&n,&m);
for(i=1;i<=m;++i){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
add(n-1,n,inf/4);
ans=dfs(0,0);
printf("%d",ans-inf/4);
// system("pause");
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】