首页 > 代码库 > JZOJ 1312:关灯问题
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 long17 #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 first21 #define se second22 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 }
JZOJ 1312:关灯问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。