luogu1043【2003普及】数字游戏(区间dp)
2017-07-30 20:07
309 查看
在后面再复制一遍,把环变成链。dp[k][i][j]表示把i…j(包括i,j)分成m部分能获得的最值。状态数O(mn2),决策O(n),转移时间O(1),总的时间复杂度O(mn3)
#include <cstdio> #include <cstring> #include <iostream> #define inf 1000000000 #define ll long long using namespace std; int const N=105; int n,m,a ,sum ,fmin[10] ,fmax[10] ,ansmin=inf,ansmax=0; int main(){ // freopen("game.in","r",stdin); // freopen("game.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); a[n+i]=a[i]; } for(int i=1;i<=n*2;i++) for(int j=i;j<=n*2;j++){ sum[i][j]=(sum[i][j-1]+a[j])%10; if(sum[i][j]<0) sum[i][j]+=10; } for(int i=1;i<=n<<1;i++) for(int j=1;j<=n<<1;j++) for(int k=1;k<=9;k++) fmin[k][i][j]=inf,fmax[k][i][j]=0; for(int i=1;i<=n<<1;i++) for(int j=i;j<=n<<1;j++) fmin[1][i][j]=fmax[1][i][j]=sum[i][j]; for(int k=2;k<=m;k++){ for(int i=1;i<=n<<1;i++) for(int j=i;j<=n<<1;j++) for(int p=i+k-1-1;p<=j-1;p++){ fmin[k][i][j]=min(fmin[k][i][j],fmin[k-1][i][p]*sum[p+1][j]); fmax[k][i][j]=max(fmax[k][i][j],fmax[k-1][i][p]*sum[p+1][j]); } } for(int i=1;i<=n;i++) ansmax=max(fmax[m][i][i+n-1],ansmax),ansmin=min(fmin[m][i][i+n-1],ansmin); printf("%d\n%d",ansmin,ansmax); return 0; }
相关文章推荐
- 区间dp——[2003NOIP普及组]数字游戏
- NOIP 2003 普及组 数字游戏
- luogu 1043 数字游戏(区间dp)
- noip2003普及组-数字游戏
- 【C++心路历程21】NOIP2003普及组复赛第4题数字游戏
- wikioi-天梯-普及一等-区间dp-1166:矩阵取数游戏
- wikioi1085 - 数字游戏(区间DP或者划分DP)
- [Wikioi 1025][NOIP 2003普及组]数字游戏
- noip2003 数字游戏 (区间动归)
- codevs 1085 数字游戏 (环形区间dp+负数取膜)
- 【DP】洛谷P1043数字游戏
- CodeVS 1090 [NOIP 2003] 区间DP 解题报告
- uva 10891 sum游戏(区间dp)
- luogu1057【2008普及】传球游戏(dp)
- 普通DP——[ 2008NOIP普及组 ]传球游戏
- nyoj 1111 游戏人生(区间DP)
- codevs1166 矩阵取数游戏(区间DP)
- qscoj 喵哈哈村的打印机游戏(区间dp)
- vijos 1218 数字游戏(环形dp)
- 【bzoj2121】字符串游戏 区间dp