JZOJ 1312:关灯问题

传送门

少见的DP再DP题目。题面不短,但是可以看出来这是一道DP题。而且正解的算法复杂度应该是$O(N^3)$。而且给了部分$O(N^4)$的算法的分。可以看出来要AC是要在DP上加上优化的。

设$g[i][j]$表示$[i,j]$内满足条件的最大答案贡献,这个用背包可以很轻松的处理出来。然后再设$f[i][k]$表示前$i$个分$k$组的最大答案。可以得到如下状态转移

$f[i][k]=max\{ f[j-1][k-1]+g[j][i] \}$

把背包上的枚举优化掉一维就行了。

代码实现上也存在诸多细节。

 1 //OJ 1312
 2 //by Cydiater
 3 //2016.10.6
 4 #include <iostream>
 5 #include <cstring>
 6 #include <string>
 7 #include <algorithm>
 8 #include <queue>
 9 #include <map>
10 #include <ctime>
11 #include <iomanip>
12 #include <cstdlib>
13 #include <cstdio>
14 #include <cmath>
15 using namespace std;
16 #define ll long long
17 #define up(i,j,n)        for(int i=j;i<=n;i++)
18 #define down(i,j,n)        for(int i=j;i>=n;i--)
19 #define pii pair<int,int>
20 #define fi first
21 #define se second
22 const int MAXN=1e3+5;
23 const int oo=0x3f3f3f3f;
24 inline int read(){
25     char ch=getchar();int x=0,f=1;
26     while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();}
27     while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
28     return x*f;
29 }
30 int N,M,T,g[MAXN][MAXN],pack[MAXN*MAXN],f[MAXN][MAXN];
31 pii light[MAXN*MAXN];
32 namespace solution{
33     void init(){
34         N=read();M=read();T=read();
35         up(i,1,N){
36             int x=read(),y=read();
37             light[i]=make_pair(x,y);
38         }
39     }
40     void pret(){
41         memset(g,0,sizeof(g));
42         up(i,1,N){
43             memset(pack,0,sizeof(pack));
44             up(j,i,N){
45                 down(k,(N-i+1)*T,light[j].fi)pack[k]=max(max(pack[k],pack[k-1]),pack[k-light[j].fi]+light[j].se);
46                 g[i][j]=g[j][i]=pack[(j-i+1)*T];
47             }
48         }
49     }
50     void DP(){
51         memset(f,0,sizeof(f));
52         up(i,1,N)up(k,1,min(M,i))up(j,k,i)f[i][k]=max(f[i][k],f[j-1][k-1]+g[j][i]);
53         cout<<f[N][M]<<endl;
54     }
55 }
56 int main(){
57     //freopen("input.in","r",stdin);
58     using namespace solution;
59     init();
60     pret();
61     DP();
62     return 0;
63 }

时间: 2024-11-09 21:19:45

JZOJ 1312:关灯问题的相关文章

[jzoj]1383.奇怪的问题

Link https://jzoj.net/senior/#main/show/1383 Problem Alice总是会提出很多奇怪的问题,一天他让他的朋友Bob跟他一起研究一个奇怪的问题.问题是:[A,B]中有多少个数满足组成这个数的数字之和为S,另一个问题是[A,B]内满足这一要求最小的数是哪个? 编程帮Bob解决这个问题. Solution 30分 显然可以使用暴力枚举,像我这样的渣渣,考试的时候想到数位DP,设完一个不完整的状态,根本不知道如何统计答案 100分 聪明的人都知道,若要求

HDU 1312 ----- Red and Black 入门搜索 DFS解法

HDU 1312 ----- Red and Black  入门搜索  http://acm.hdu.edu.cn/showproblem.php?pid=1312 /*HDU 1312 ----- Red and Black 入门搜索 */ #include <cstdio> int n, m; //n行m列 int cnt, startx, starty; char mapp[25][25]; /*找一个连通的区域里可以走的块*/ void dfs(int x, int y){ if (x

HDU 1312 Red and Black (搜索)

Red and Black Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 9795    Accepted Submission(s): 6103 Problem Description There is a rectangular room, covered with square tiles. Each tile is colore

hdoj 1312 Red and Black 【BFS】

题意:一共有四个方向,从'@'出发,找能到达'.'的个数, #是不能通过的. 策略:广搜. 这道题属于最简单的bfs了. 代码: #include<stdio.h> #include<string.h> #include<queue> using std::queue; bool vis[25][25]; char s[25][25]; int n, m; int ans = 0; struct node{ int x, y; }; node st; const int

[jzoj]4216.【NOIP2015模拟9.12】平方和

Link https://jzoj.net/senior/#main/show/4216 Description 给出一个N个整数构成的序列,有M次操作,每次操作有一下三种: ①Insert Y X,在序列的第Y个数之前插入一个数X: ②Add L R X,对序列中第L个数到第R个数,每个数都加上X: ③Query L R,询问序列中第L个数到第R个数的平方和. Solution 我不会告诉你这道题我打了10000+byte,并且改了2个月,50多个小时,删掉代码重打了5次.这道题用splay来

HDU 1312 Red and Black (dfs)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1312 Red and Black Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 17773    Accepted Submission(s): 10826 Problem Description There is a rectangula

1312 Red and Black

http://acm.hdu.edu.cn/showproblem.php?pid=1312 1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <stdio.h> 5 int n,m; 6 char data[30][30]; 7 using namespace std; 8 int f(int i,int j) 9 { 10 if(i<0||j&g

hud 1312 Red and Black

题目: 链接:点击打开链接 题意: DFS搜索 算法: dfs 思路: 简单题 代码: #include<iostream> #include<cstdio> #include<cstring> using namespace std; int w,h; char s[30][30]; int vis[30][30]; int cnt; void dfs(int x,int y) { if(s[x][y] == '#' || vis[x][y]) return ; if

IOS 关灯游戏

一, 首先为window创建根视图控制器 在AppDelegate.h文件中 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions //为window创建根视图控制器 RootViewController *rootViewController = [[RootViewController alloc]init]; self.wind