↓ 跳过正文
  1. Posts/

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

·526 字·2 分钟

http://poj.org/problem?id=3249

题意:
#

给一个DAG,现要从一条入度为0的点到一个出度为0的点,问最大点权和。

思路:
#

其实比较容易想到搜…不过复杂度会炸?

由于到一个点的最大点权和,需要更新完所有到达它的路线之后才能确定。

容易联想到拓扑排序,我们可以在拓扑排序的同时做dp

dp[v] = max(dp[v],dp[u]+a[v]),初始化对于入度为0的点,dp[i] = val[i].

其实拓扑+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,m;
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        dp[v] = max(dp[v],dp[cur]+val[v]);
57        in[v]--;
58        if (in[v]==0) Q.push(v);
59    }
60    }
61}
62int main()
63{
64    #ifndef  ONLINE_JUDGE
65    freopen("./in.txt","r",stdin);
66  #endif
67    while (~scanf("%d %d",&n,&m))
68    {
69        init();
70        for ( int i = 1 ; i <= n ; i++) scanf("%d",&val[i]);
71        while (m--)
72        {
73        int x,y;
74        scanf("%d %d",&x,&y);
75//      cout<<"x:"<<x<<" y:"<<y<<endl;
76        edge[x].PB(y);
77        out[x]++;
78        in[y]++;
79        }
80        topo();
81        int ans = -inf;
82        for ( int i = 1 ; i <= n ; i++) if (!out[i]&&dp[i]>ans) ans = dp[i];
83        printf("%d\n",ans);
84    }
85
86
87
88  #ifndef ONLINE_JUDGE
89  fclose(stdin);
90  #endif
91    return 0;
92}

相关文章

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

·289 字·1 分钟
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 字·1 分钟
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 字·1 分钟
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..果然傻了。。

BZOJ 2748: [HAOI2012]音量调节 (dp)

·820 字·2 分钟
2748: [HAOI2012]音量调节 # Time Limit: 3 Sec Memory Limit: 128 MB Submit: 1814 Solved: 1148 [Submit][Status][Discuss] Description # 一个吉他手准备参加一场演出。他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都要改变一次音量。在演出开始之前,他已经做好了一个列表,里面写着在每首歌开始之前他想要改变的音量是多少。每一次改变音量,他可以选择调高也可以调低。 音量用一个整数描述。输入文件中给定整数beginLevel,代表吉他刚开始的音量,以及整数maxLevel,代表吉他的最大音量。音量不能小于0也不能大于maxLevel。输入文件中还给定了n个整数c1,c2,c3…..cn,表示在第i首歌开始之前吉他手想要改变的音量是多少。 吉他手想以最大的音量演奏最后一首歌,你的任务是找到这个最大音量是多少。