nyoj304 节能 动态规划
来源:互联网 发布:思启网络 编辑:程序博客网 时间:2024/04/26 06:19
这个题自己琢磨了好久,也没想出状态转移方程,一经提醒才大悟啊!
这是个区间型DP,先开门见山看一下怎样存状态的吧:d[i][j][0] 所存的状态是在i到j这个区间所有灯已关闭,并且机器人位于i点时所消耗的最小功率。 d[i][j][1]所代表就是 i到j区间所有灯已关闭,位于j点时 所消耗的最小功率。
d[i][j][0] 区间(i, j)的灯都关闭了,机器人正位于i点 , 上一步可能是从j点过来 或者从i+1点过来,有两个前一状态,
即 d[i][j][0] = min(d[i+1][j][0] + (机器人从i+1 走到 i 点期间 其余亮着的灯所消耗的功率) , d[i+1][j][1] + (从j点走到i点期间 其余没关的灯所消耗的功率)) .
同样d[i][j][1] = min(d[i][j-1][0] + (从i点到j点消耗的功率), d[i][j-1][1] + (从j-1到j点消耗的功率))。
#include<iostream>#include<cstdio>#include<string.h>#include<algorithm>#include<queue>using namespace std;//l、r分别表示最左面和最右面灯所在的坐标,st是开始的路灯,w[i]代表位于坐标i的路灯的功率int l, r, n, st, sum, w[1005], d[1005][1005][4];void dp(){ for(int i = 1; i <= (r - l); i++)//以区间相距i为主循环 { for(int j = l; j <= (r-i); j++) { //这一部分求的是d[i][i+j][0] sum = d[j+1][j+i][2]; //如果上一状态已求出,那么他所存的剩余灯消耗的功率一定为正数 if(sum != -1) { d[j][i+j][2] = d[j+1][i+j][2] - w[j];//更新当前剩余的灯的功率和 //如果上一状态是可行的、合法的而且已求出, 那么他的状态一定是>=0的 if(d[j+1][j+i][0] >= 0 && d[j+1][j+i][1] >= 0) { if(d[j+1][j+i][0] + sum < d[j+1][j+i][1] + i*sum) d[j][i+j][0] = d[j+1][i+j][0] + sum; else d[j][i+j][0] = d[j+1][i+j][1] + i*sum; } //如果上两状态中只有一个是可行的,就只能由那个得来 else if(d[j+1][j+i][0] >= 0 || d[j+1][j+i][1] >= 0) { if(d[j+1][j+i][0] >= 0) d[j][i+j][0] = d[j+1][i+j][0] + sum; else d[j][i+j][0] = d[j+1][i+j][1] + i*sum; } } //这一部分求的是d[j][j+i][1] sum = d[j][i+j-1][2]; if(sum != -1) { d[j][i+j][2] = d[j][i+j-1][2] - w[i+j]; if(d[j][i+j-1][0] >= 0 && d[j][i+j-1][1] >= 0) { if(d[j][i+j-1][0] + i*sum < d[j][i+j-1][1] + sum) d[j][i+j][1] = d[j][i+j-1][0] + i*sum; else d[j][i+j][1] = d[j][i+j-1][1] + sum; } else if(d[j][i+j-1][0] >= 0 || d[j][i+j-1][1] >= 0) { if(d[j][j+i-1][0] >= 0) d[j][i+j][1] = d[j][i+j-1][0] + i*sum; else d[j][i+j][1] = d[j][i+j-1][1] + sum; } } } }}int main(){ while(scanf("%d", &n) != EOF) { memset(w, 0, sizeof(w)); memset(d, -1, sizeof(d));//先初始化所有状态为-1,一个不可能的值 scanf("%d", &st); sum = 0; l = 10e5; r = 0; for(int i = 1; i <= n; i++) { int a, b; scanf("%d%d", &a, &b); w[a] = b; sum += b;//这里sum存的是除去开始路灯,其他所有灯的功率和 if(i == st) { sum -= b; st = a; } if(a < l) l = a; if(a > r) r = a; } //d[i][j][2] 存储关闭i至j区间后 其他没关的灯的功率和 d[st][st][0] = d[st][st][1] = 0; d[st][st][2] = sum; dp(); int ans = min(d[l][r][0], d[l][r][1]); printf("%d\n", ans); } return 0;}
0 0
- nyoj304 节能 动态规划
- nyoj304节能(区间dp)
- NYOJ304
- 节能
- 动态规划!!!动态规划!!!
- NYOJ304(区间DP)
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 栈的基本操作
- 物联RFID第二次作业5.6和5.8题
- java虚拟机构造原理
- 函数与变量的预解析
- 【SeedCoder 2015年热身题1 常规】质数问题(题目+答案)
- nyoj304 节能 动态规划
- (转)Hadoop、Spark、HBase与Redis的适用性见解
- 18. PHP Callback 回调类型
- 图的前向星表示法
- Coursera Machine Learning 学习笔记(十三)
- Linux中常用操作命令
- 图像处理---关于像素坐标矩阵变换(平移,旋转,缩放,错切)
- 如何解决Protel 99SE添加库文件时出现“File is not recognized“
- bzoj3098 卡掉HASH