URAL 1900. Brainwashing Device
来源:互联网 发布:java crm源码之家 编辑:程序博客网 时间:2024/06/06 09:47
乍看此题,还以为是扫描线+贪心,每次都扫描出最多的那个站,但是时间复杂度太高,而且写到一半的时候发现了反例. . . . .
接下来开始推式子:
dp[ i ][ j ] = max(dp[ k1 ][ j ],dp[ k2 ][ j -1] + ans[site[ k2 ][j-1]+1][i])。
k1 ∈[j,i],k2 ∈[j-1,i].
site[ i ][ j ]表示的dp[ i ][ j ]这种情况下最右边的洗脑设备的位置.
ans[ i ][ j ]表示 以 k ∈ [ i , j ] 为始发站,经过 j 且不以 j 为终点的客人数量.
好了,理清上面的思路后问题的难点就变成了 如何统计出 ans[ ][ ]。
如果单纯的暴力枚举时间复杂度是o(n^4),二维的线段树倒是可以胜任,但是我忘了怎么写了。。。
然后学姐说可以试一试能否转化成简单的矩阵DP。
设,Map[ i ][ j ]存储的为 i 到 j 的客流量,i >= j 时,Map[ i ][ j ] = 0。
则ans[ x ][ y ] = sigma Map[ i ][ j ] ( x <= i <= y ,y < j <= n)。
接下来可以用 2*n^2 的时间将Map[ i ][ j ]处理成 (1,1) 到 ( i , j )的矩形范围内元素的和。
则 ans[ i ][ j ] = Map[ j ][ n ] - Map[ j ][ j ] - Map[ i-1 ][ n ] + Map[ i-1 ][ j ]。
显然这种方法预处理的时间较高,但查询只需要o(1)。缺点在于不能更新。
对于打印路径只需要在dp的时候记录一下前驱即可,不再赘述。
就这个烂题竟然卡了两天。。。。
#include <iostream>#include <algorithm>#include <cstdlib>#include <cstdio>#include <cstring>#include <queue>#include <cmath>#include <stack>#pragma comment(linker, "/STACK:1024000000");#define EPS (1e-8)#define LL long long int#define ULL unsigned long long int#define _LL __int64#define _INF 0x3f3f3f3f#define INF 40000000#define Mod 1000000009using namespace std;int Map[501][501];struct N{ int site,data,pn,pm;}dp[501][501];int ans[501][501];bool path[510];void dfs(int n,int m){ if(n == 0 || m == 0) return ; if(dp[n][m].pm != m) path[n] = true; dfs(dp[n][m].pn,dp[n][m].pm);}int main(){ int n,m,i,j,k,t; scanf("%d %d",&n,&m); memset(Map,0,sizeof(Map)); for(i = 1;i < n; ++i) { for(j = i+1;j <= n; ++j) { scanf("%d",&Map[i][j]); } } for(i = 1;i <= n; ++i) { for(j = 1;j <= n; ++j) { Map[i][j] += Map[i][j-1]; } } for(j = 1;j <= n; ++j) { for(i = 1;i <= n; ++i) { Map[i][j] += Map[i-1][j]; } } memset(ans,0,sizeof(ans)); for(i = 1;i <= n; ++i) { for(j = 1;j <= n; ++j) { ans[i][j] = Map[j][n] - Map[j][j] - Map[i-1][n] + Map[i-1][j]; } } for(i = 0;i <= n; ++i) { dp[i][0].data = 0; dp[i][0].site = 0; } for(i = 1;i <= n; ++i) { for(t = min(i,m),j = 1;j <= t; ++j) { dp[i][j].data = dp[j-1][j-1].data + ans[dp[j-1][j-1].site+1][i]; dp[i][j].site = i; dp[i][j].pn = j-1; dp[i][j].pm = j-1; for(k = j;k <= i; ++k) { if(dp[k][j].data > dp[k][j-1].data + ans[dp[k][j-1].site+1][i]) { if(dp[k][j].data > dp[i][j].data) { dp[i][j] = dp[k][j]; dp[i][j].pn = k; dp[i][j].pm = j; } } else { if(dp[k][j-1].data + ans[dp[k][j-1].site+1][i] > dp[i][j].data) { dp[i][j].data = dp[k][j-1].data + ans[dp[k][j-1].site+1][i]; dp[i][j].site = i; dp[i][j].pn = k; dp[i][j].pm = j-1; } } } } } memset(path,false,sizeof(path)); dfs(n-1,m); printf("%d\n",dp[n][m].data); for(i = 1;i <= n;++i) { if(path[i]) { printf("%d",i); break; } } for(++i;i <= n;++i) { if(path[i]) { printf(" %d",i); } } puts(""); return 0;}
- URAL 1900. Brainwashing Device
- URAL 1900 Brainwashing Device
- URAL 1900 Brainwashing Device (dp)
- URAL 1900. Brainwashing Device(dp+输出路径)
- URAL 1900 Brainwashing Device (dp,4级)
- 【URAL 1900】Brainwashing Device(预处理区间和+DP)
- Timus 1900 Brainwashing Device
- Lost S03Ep07 - Brainwashing Scene
- URAL
- 【ural】
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- C++静态成员函数详解
- JAVA 输出指定字符串所有排列组合
- Balloon Comes! 1170
- POJ 1028——Web Navigation
- Servlet线程安全的解决方法
- URAL 1900. Brainwashing Device
- 如何在eclipse里添加logcat,以及添加过滤器
- java整数和byte数组之间的转换
- safe nic
- Mysql启动错误1067解决办法
- ExtJs读取servlet传送数据
- 2.10 IplImage结构和 Mat结构的转换
- window 脚本指定目录
- java.lang.NoClassDefFoundError: com.baidu.mapapi.BMapManager解决办法