↓ Skip to main content
  1. Posts/

poj 1949 Chores (拓扑排序+dp)

·500 words·1 min
Note: This article is available in Chinese only. 本文暂无英文版本。 View original

http://poj.org/problem?id=1949
#

题意:
#

有n个任务,第i个任务需要时间xi来完成,并且第i个任务必须在它 “前面的” 某些任务完成之后才能开始。

给你任务信息,问你最短需要多少时间来完成任务。

思路:
#

拓扑排序+dp

拓扑排序的过程中做个dp,可以保证dp的顺序…

对于这道题,找出每条依赖链,然后做dp即可。

代码实现
  1/* ***********************************************
  2Author :111qqz
  3Created Time :2017年11月07日 星期二 13时52分27秒
  4File Name :3249.cpp
  5************************************************ */
  6
  7#include <iostream>
  8#include <cmath>
  9#include <queue>
 10#include <cstdio>
 11#include <cstring>
 12#define PB push_back
 13#define fst first
 14#define sec second
 15#define lson l,m,rt<<1
 16#define rson m+1,r,rt<<1|1
 17#define ms(a,x) memset(a,x,sizeof(a))
 18typedef long long LL;
 19#define pi pair < int ,int >
 20#define MP make_pair
 21
 22using namespace std;
 23const double eps = 1E-8;
 24const int dx4[4]={1,0,0,-1};
 25const int dy4[4]={0,-1,1,0};
 26const int inf = 0x3f3f3f3f;
 27const int N=1E5+7;
 28vector <int>edge[N];
 29int in[N],out[N];
 30int n;
 31int dp[N];
 32int val[N];
 33void init()
 34{
 35    for ( int i = 0 ; i < N ; i++) edge[i].clear();
 36    ms(in,0);
 37    ms(out,0);
 38    ms(dp,0xca);
 39 //   cout<<"dp:"<<dp[1]<<endl;
 40}
 41void topo()
 42{
 43    queue<int>Q;
 44    for ( int i = 1 ; i <= n ; i++)
 45    if (in[i]==0) Q.push(i),dp[i] = val[i];
 46
 47    while (!Q.empty())
 48    {
 49    int cur = Q.front();
 50//  cout<<"cur:"<<cur<<endl;
 51    Q.pop();
 52    int siz = edge[cur].size();
 53    for ( int i = 0 ; i < siz ; i++)
 54    {
 55        int v = edge[cur][i];
 56//      printf("%d->%d val[v]:%d dp[cur]: %d dp[v]:%d ",cur,v,val[v],dp[cur],dp[v]);
 57        dp[v] = max(dp[v],dp[cur]+val[v]);
 58//      printf("new dp[v]:%d\n",dp[v]);
 59        in[v]--;
 60        if (in[v]==0) Q.push(v);
 61    }
 62    }
 63}
 64void pr()
 65{
 66    for ( int i = 1 ; i <= n ; i++) printf("%d%c",dp[i],i==n?'\n':' ');
 67}
 68int main()
 69{
 70#ifndef  ONLINE_JUDGE
 71    freopen("./in.txt","r",stdin);
 72#endif
 73    while (~scanf("%d",&n))
 74    {
 75    init();
 76    for ( int i = 1 ; i <= n ; i++)
 77    {
 78        int x,m;
 79        x = i;
 80        scanf("%d %d",&val[i],&m);
 81        while (m--)
 82        {
 83        int y;
 84        scanf("%d",&y);
 85        //      cout<<"x:"<<x<<" y:"<<y<<endl;
 86        edge[y].PB(x);
 87        out[y]++;
 88        in[x]++;
 89        }
 90    }
 91    topo();
 92    int ans = -inf;
 93//  pr();
 94    for ( int i = 1 ; i <= n ; i++) if (!out[i]&&dp[i]>ans) ans = dp[i];
 95    printf("%d\n",ans);
 96    }
 97
 98
 99
100#ifndef ONLINE_JUDGE
101    fclose(stdin);
102#endif
103    return 0;
104    }

Related

poj 3249 Test for Job (拓扑排序+dp)

·526 words·2 mins
http://poj.org/problem?id=3249 题意: # 给一个DAG,现要从一条入度为0的点到一个出度为0的点,问最大点权和。 思路: # 其实比较容易想到搜…不过复杂度会炸?

leetcode 152. Maximum Product Subarray (最大连续子序列乘积,dp)

·289 words·1 min
Find the contiguous subarray within an array (containing at least one number) which has the largest product. For example, given the array [2,3,-2,4], the contiguous subarray [2,3] has the largest product = 6. 思路:由于有正,有负,还有0.。。所以比最大子串之和要复杂一些。。。 dp[i].max表示到当前位置的最大乘积。

leetocde 63. Unique Paths II

·337 words·1 min
Follow up for “Unique Paths”: Now consider if some obstacles are added to the grids. How many unique paths would there be? An obstacle and empty space is marked as 1 and 0 respectively in the grid. For example, There is one obstacle in the middle of a 3x3 grid as illustrated below. 1[ 2 [0,0,0], 3 [0,1,0], 4 [0,0,0] 5] The total number of unique paths is 2. 题意:从左上到右下的方案数,有些点不能走。

leetcode 64. Minimum Path Sum (二维dp)

·371 words·1 min
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time. 数字三角形。。。。从左上到右下问最短路径。。每次只能向下或者向右。。。 wa了一次。。。是因为边界值赋值成了0.。。求最短路径显然因为赋值成inf才对orz..果然傻了。。