LightOJ-1031-区间dp,dfs
2016-10-18 20:07
369 查看
题目大意:有n张卡片,有两个人,每次可以从左边或者右边拿走几张卡片,他们都是想自己赢,所以每次选择都是最优的,问最后差值是多少;
题目解析:对于区间[l,r],用dp[l,r]表示其区间能选择的最大值,那么假设从左边拿走了i个卡片,那么第二个人能选的最大值就是dp[l+i][r],第一个就是sum[r]-sum[l-1]-dp[l+i][r],所以dp[l][r]=max(dp[l][r],sum[r]-sum[l-1]-dp[l+i][r]),这里我们可以dfs,记忆化搜索来减少时间复杂度;
AC代码:
题目解析:对于区间[l,r],用dp[l,r]表示其区间能选择的最大值,那么假设从左边拿走了i个卡片,那么第二个人能选的最大值就是dp[l+i][r],第一个就是sum[r]-sum[l-1]-dp[l+i][r],所以dp[l][r]=max(dp[l][r],sum[r]-sum[l-1]-dp[l+i][r]),这里我们可以dfs,记忆化搜索来减少时间复杂度;
AC代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> using namespace std; const int inf=0x3fffffff; bool vis[110][110]; int sum[110],dp[110][110],a[110]; int dfs(int l,int r) { if(l>r) return 0; if(vis[l][r]) return dp[l][r]; if(l==r) return a[l]; dp[l][r]=-inf; int all=sum[r]-sum[l-1],i; for(i=1;l+i<=r+1;i++) { dp[l][r]=max(dp[l][r],all-dfs(l+i,r)); } for(i=1;r-i>=l-1;i++) { dp[l][r]=max(dp[l][r],all-dfs(l,r-i)); } vis[l][r]=1; return dp[l][r]; } int main() { int cas,c,i,n; scanf("%d",&cas); for(c=1;c<=cas;c++) { memset(sum,0,sizeof(sum)); memset(vis,0,sizeof(vis)); scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i]; } printf("Case %d: %d\n",c,2*dfs(1,n)-sum ); } return 0; }
相关文章推荐
- lightoj 1031 - Easy Game(区间DP)
- lightoj 1031 Easy Game (区间dp 博弈)
- lightoj1031 - Easy Game【区间dp】
- LightOJ1031 Easy Game(区间DP)
- lightoj 1031 区间dp
- LightOJ 1031 区间dp
- lightoj 1031【区间DP】
- LightOJ - 1031 Easy Game(区间DP)
- LightOJ 1031 - Easy Game【区间dp】
- LightOJ-1033-区间dp,dfs
- lightoj 1031 - Easy Game 【区间dp】
- [区间DP] A - Easy Game LightOJ - 1031
- Lightoj 1031 - Easy Game (区间DP)
- LightOJ-1031 博弈 区间DP
- LightOJ 1031 - Easy Game (区间dp)
- lightoj 1031 - Easy Game 【区间dp】360 2017笔试编程题3
- LightOJ 1031 Easy Game(区间DP)
- lightoj 1031 被区间dp虐哭...看题解才学会
- Lightoj 1031 区间DP
- Lightoj 1031(区间dp)