ACdream 1100 瑶瑶饿了(Folyd+完全背包问题)

Description
你们肯定都不知道从前有个很聪明的妹子,她的名字叫瑶瑶(tsyao)。一天,瑶瑶在自己家里建造了一个魔法阵。她在魔法阵找吃的,这个魔法阵有n种食物,每种食物有xi份,而且每种食物位于魔法阵的不同位置(相同食物位于相同位置)。吃第i种食物,每一份会消耗ti的时间,获得wi的价值。当然这个魔法阵有魔力,每次吃一种食物后瑶瑶会传送回到自己家(耗时0),并且不能再吃该种食物。另外,从魔法阵x位置到y位置会消耗bi的时间。如果有路能够让瑶瑶从x到达z,从z到达y,那么瑶瑶是可以从x经过z到达y的,但是瑶瑶不能在z点吃东西,否则她又会被送回家。。。。现在瑶瑶家位于0号位置,她有T的时间吃食物,她想在T时间内吃得最大的价值。
Input
第1行三个整数n, m, T。
接下来n行 ,每行三个整数xi, wi, ti为每种食物的份数xi,价值wi和吃每一份食物的时间ti,第i种食物位于魔法阵位置i。
接下来m行,每行三个整数x, y, ti表示从位置x到位置y有一条消耗时间为ti的路(有向图,可能有多条从x到y的路)。
1 ≤ n ≤ 100 , 1 ≤ m ≤ 5000 , 1 ≤ T ≤ 1000
1 ≤ xi ≤ 100, 1≤ wi ≤ 10^7, 1 ≤ ti ≤ T
1 ≤ x ≤ n, 1 ≤ y ≤ n
Output
输出一行 ,为瑶瑶在T时间内获得的最大价值。
Sample Input
3 5 10
1 1 1
3 2 4
1 10 5
0 1 1
0 2 5
0 3 1
1 2 1
2 3 1
Sample Output
11
Solution
在背包前,物品的容量得加上到这个物品的距离。先Floyd求最短路,再完全背包
Code

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define maxn 111
typedef long long ll;
int n,m,T;
int d[maxn][maxn],x[maxn],w[maxn],t[maxn];
ll dp[1111];
int main()
{
    scanf("%d%d%d",&n,&m,&T);
    for(int i=1;i<=n;i++)
        scanf("%d%d%d",&x[i],&w[i],&t[i]);
    memset(d,31,sizeof(d));
    for(int i=0;i<=n;i++)
        d[i][i]=0;
    for(int i=0;i<m;i++)
    {
        int u,v,cost;
        scanf("%d%d%d",&u,&v,&cost);
        d[u][v]=min(d[u][v],cost);//两点间路径可能有多条 
    }
    for(int k=0;k<=n;k++)//Folyd 
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
                d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
    memset(dp,0,sizeof(dp));//初始化 
    for(int i=0;i<=n;i++)//完全背包 
        for(int j=T;j>=0;j--)
        {
            int cost=j+d[0][i];//背包前加上到该物品的距离 
            for(int k=0;k<=x[i];k++)
            {
                if(cost+k*t[i]>T)
                    break;
                dp[cost+k*t[i]]=max(dp[cost+k*t[i]],dp[j]+k*w[i]);
            }
        }
    printf("%lld\n",dp[T]);
    return 0;
} 

你可能感兴趣的:(ACdream 1100 瑶瑶饿了(Folyd+完全背包问题))