zoukankan      html  css  js  c++  java
  • [DP]JZOJ 3046 游戏

    Description

    游戏规则如下:给定两个正整数数列,一个游戏者通过若干次操作完成游戏。每一次操作,选择两个正整数k1和k2。将第一个数列的最后连续k1个数删除,它们的和记为S1;将第二个数列的最后连续K2个数删除,它们的和记为S2。这一次操作的得分就是(S1-K1)* (S2-K2 )。直到两个数列都清空了为止,所以不允许一个数列空了,而另一个数列中还有数。游戏的总得分就是每一次操作的得分总和。求最小的总得分。 

     

    Input

    第一行是两个整数L1和L2,分别表示第一个数列和第二个数列的初始长度。 


    第二行有L1个正整数,是第一个数列的数。 


    第三行有L2个正整数,是第二个数列的数。 


    数列中的数都不超过1000。 

    Output

    一个整数,表示最小的总得分。 

     

    Sample Input

    3 2
    1 2 3
    1 2

    Sample Output

    2
     

    Data Constraint

     
     

    Hint

    对于20%的数据,L1,L2<=20; 


    对于40%的数据,L1,L2<=200;


    对于100%的数据,1<=L1,L2<=2000。

    分析

    对于$(k1-s1)*(k2-s2)$这个柿子,不难发现$k1-s1=Sigma k-1$

    所以事先给所有值-1,柿子变成$k1*k2=Sigma k1_i imesSigma k2_i$

    DP的柿子就是$f[i][j]=min(f[i+1][j],f[i+1][j+1],f[i][j+1])+a[i]*b[j]$

    #include <iostream>
    #include <cstdio>
    #include <memory.h>
    using namespace std;
    const int N=2e3+10;
    int l1,l2;
    int a[N],b[N],f[N][N];
    
    int main() {
        scanf("%d%d",&l1,&l2);
        for (int i=1;i<=l1;i++) scanf("%d",&a[i]),a[i]--;
        for (int i=1;i<=l2;i++) scanf("%d",&b[i]),b[i]--;
        memset(f,0x7f,sizeof f);
        f[l1+1][l2+1]=0;
        for (int i=l1;i;i--)
            for (int j=l2;j;j--)
                f[i][j]=min(f[i+1][j],min(f[i+1][j+1],f[i][j+1]))+a[i]*b[j];
        printf("%d",f[1][1]);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    hibernate课程 初探单表映射2-7 hbm配置文件常用设置
    SQL partition (小组排序)
    修改input的text 通过jquery的html获取值 未变化
    ASP.NET MVC5使用Area区域
    MVC 缓存
    C# 后台访问webapi
    分布式系统
    滴滴出行技术总监:关于技术选型的那些事儿
    Json Self referencing loop detected
    VMWare 安装 Eclipse
  • 原文地址:https://www.cnblogs.com/mastervan/p/11136096.html
Copyright © 2011-2022 走看看