zoukankan      html  css  js  c++  java
  • 【NOIP2010】乌龟棋

    本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1541


    呃呃,确实想不粗来。虽然最近做了好几道DP题,但还是无法保证想得出状态以及状态转移方程。。。不过顺便了解到了DP和贪心的“血缘关系”:如果对于第i个状态,只需第i-1个状态就可以推出第i个状态,对应的推导过程就叫贪心,这种推导过程也是数学上常用的数学归纳法;如果对于第i个状态,仅仅由第i-1个状态无法推出,而需要综合考虑前i-1个状态才能推出,对应的推导过程就叫动态规划,这种方法也叫第二数学归纳法。

    好了,言归正传,我们可以定义状态dp[i][j][k][l]表示这四种卡片的使用数量(状态的得出可以参考数据范围的提示:只有四种卡牌,每种数量不超过40),那么dp[i][j][k][l]=max(dp[i-1][j][k][l],dp[i][j-1][k][l],dp[i][j][k-1][l],dp[i][j][k][l-1])+a[1+i+2*j+3*k+4*l],特别的,dp[0][0][0][0]=a[1],一张都不使用时,棋子处于起点,也有相应分数。具体细节详见代码。

     1 #include<cstdio>
     2 inline int max(int a,int b) {return a>b?a:b;}
     3 const int maxn=355,maxm=125,maxe=45;
     4 int n,m,a[maxn],b,num[5],dp[maxe][maxe][maxe][maxe],ans;
     5 int main() {
     6     scanf("%d%d",&n,&m);
     7     for(int i=1;i<=n;++i) scanf("%d",&a[i]);
     8     for(int i=1;i<=m;++i) {scanf("%d",&b);++num[b];}
     9     dp[0][0][0][0]=a[1];
    10     for(int i=0;i<=num[1];++i)
    11         for(int j=0;j<=num[2];++j)
    12             for(int k=0;k<=num[3];++k)
    13                 for(int l=0;l<=num[4];++l) {
    14                     int to=i+2*j+3*k+4*l+1;
    15                     if(i>0) dp[i][j][k][l]=max(dp[i][j][k][l],dp[i-1][j][k][l]+a[to]);
    16                     if(j>0) dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j-1][k][l]+a[to]);
    17                     if(k>0) dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j][k-1][l]+a[to]);
    18                     if(l>0) dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j][k][l-1]+a[to]);
    19                 }
    20     printf("%d",dp[num[1]][num[2]][num[3]][num[4]]);
    21     return 0;
    22 }
    AC代码
  • 相关阅读:
    git学习,git上建立自己的项目
    springframework3.2源码下载导入eclipse
    git学习
    java事件处理机制(自定义事件)
    quartz scheduler 2.16 之集群
    博客总目录(2007.11.12 2010.4.25)
    JS中json数据的处理
    (转载)JAVA线程池管理
    查到的一些发送邮件代码的链接
    layui时间控件,获取页面选中的时间值。
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9630181.html
Copyright © 2011-2022 走看看