Travel(HDU 4284状压dp)

时间:2024-04-12 20:33:24

题意:给n个城市m条路的网图,pp在城市1有一定的钱,想游览这n个城市(包括1),到达一个城市要一定的花费,可以在城市工作赚钱,但前提有工作证(得到有一定的花费),没工作证不能在该城市工作,但可以走,一个城市只能工作一次,问pp是否能游览n个城市回到城市1.

分析:这个题想到杀怪(Survival(ZOJ 2297状压dp)

那个题,也是钱如果小于0就挂了,最后求剩余的最大钱数,先求出最短路和

Hie with the Pie(POJ 3311状压dp)

送披萨那个题相似。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <complex>
#include <cassert>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
#define lson l,m,rt<<1
#define pi acos(-1.0)
#define rson m+1,r,rt<<11
#define All 1,N,1
#define read freopen("in.txt", "r", stdin)
#define N 1<<16
#define INF 99999999
const int mod = 1000000007;
int n,m,money,tn;
int dp[N][20],cost[120][120];
struct city{
int in,c,d;
}t[20];
void floyd(){
for(int k=1;k<=tn;++k)
for(int i=1;i<=tn;++i)
for(int j=1;j<=tn;++j)
cost[i][j]=min(cost[i][j],cost[i][k]+cost[k][j]);
}
void solve(){
int cas=(1<<n)-1;
for(int i=0;i<=cas;++i)
for(int j=0;j<n;++j)
dp[i][j]=-INF;
for(int i=0;i<n;++i)
if(money>=cost[1][t[i].in]+t[i].d)
dp[1<<i][i]=money-cost[1][t[i].in]-t[i].d+t[i].c;
for(int i=1;i<=cas;++i)
for(int j=0;j<n;++j){
if(dp[i][j]==-INF||!(i&(1<<j)))continue;
for(int k=0;k<n;++k){
if(j==k)continue;
int c=cost[t[j].in][t[k].in]+t[k].d;
if(!(i&(1<<k))&&dp[i][j]>=c){
int tot=dp[i][j]-c+t[k].c;
dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],tot);
}
}
}
int f=0;
for(int i=0;i<n;++i)
if(dp[cas][i]>=cost[1][t[i].in]){
// cout<<dp[cas][i]<<endl;
f=1;
break;
}
if(f)printf("YES\n");
else printf("NO\n");
}
int main()
{
int te;
scanf("%d",&te);
while(te--){
scanf("%d%d%d",&tn,&m,&money);
for(int i=0;i<=tn;++i)
for(int j=0;j<=tn;++j)
{
if(i==j)cost[i][j]=0;
else cost[i][j]=INF;
}
int u,v,c;
for(int i=0;i<m;++i){
scanf("%d%d%d",&u,&v,&c);
cost[u][v]=cost[v][u]=min(cost[u][v],c);
}
floyd();
scanf("%d",&n);
for(int i=0;i<n;++i)
scanf("%d%d%d",&t[i].in,&t[i].c,&t[i].d);
solve();
}
return 0;
}