zoukankan      html  css  js  c++  java
  • DP 简单题目练习

    ZOJ 1234

    这道题目我表示也还不是特别能理解。。。。还是太菜了T T

    从后往前思考,因为只要后面有多的数在,那么C肯定是存在的,只要考虑是否把前两个数加在一起作为badness值这样两种情况来考虑

    如果总数和3*j相同的话,那必然不用多考虑,它只能以前两个数的平方差作为badness值

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 int len[5005],dp[5005][1010];
     7 
     8 int main()
     9 {
    10     int T,k,n;
    11     scanf("%d",&T);
    12     while(T--){
    13         scanf("%d%d",&k,&n);
    14 
    15         memset(dp,0x3f,sizeof(dp));
    16         for(int i=0;i<=n;i++)
    17             dp[i][0]=0;
    18 
    19         k+=8;
    20         for(int i=1;i<=n;i++)
    21             scanf("%d",len+i);
    22     //i表示从i这点开始一直取到末尾,j表示取的筷子组
    23         for(int i=n-2;i>=0;i--){
    24             for(int j=1;j<=k&&n-i+1>=3*j;j++){
    25                 if(n-i+1 == 3*j)
    26                     dp[i][j] = dp[i+2][j-1] + (len[i]-len[i+1])*(len[i]-len[i+1]);
    27 
    28                 else if(n-i+1>3*j)
    29                    //这个语句表示对于最前面的那个数选不选取有两种可能性,不选,选了那么必然还要选取相邻的数和它作为一组
    30                     dp[i][j] = min(dp[i+1][j],dp[i+2][j-1] + (len[i]-len[i+1])*(len[i]-len[i+1]));
    31             }
    32         }
    33 
    34         printf("%d
    ",dp[1][k]);
    35     }
    36     return 0;
    37 }
    38     

    ZOJ 1366

    这道题目对于一种产品来说数量有多样,但我们直接用0-1背包做是会超时的,所以先把商品打包在一起,数量由1,2,4,8,16~这样叠加上去,也就是说,即使有1000个数量,也只需要数组用11个地址来保存即可。

    再根据0-1背包求解,这里最好把dp[]数组设为1元的,dp过程就逆向思考,不然二元的太耗内存,会不会爆我也没试过

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 int cnt;//表示产品的量
     6 int price[120],dp[100005];
     7 
     8 //多重背包转化成0-1背包来求解
     9 void change(int k,int pri)
    10 {
    11     int a=1;
    12     price[0]=0;
    13     while(k>a){
    14         price[++cnt] = a*pri;
    15         k-=a;
    16         a<<=1;
    17     }
    18     price[++cnt] = k*pri;
    19 }
    20 
    21 int main()
    22 {
    23     int cash,n,d,pri;
    24 
    25     while(~scanf("%d%d",&cash,&n)){
    26         cnt=0;
    27         memset(dp,0,sizeof(dp));
    28 
    29         for(int i=0;i<n;i++)
    30         {
    31             scanf("%d%d",&d,&pri);
    32             change(d,pri);
    33         }
    34 
    35         for(int i=1;i<=cnt;i++){
    36             for(int j=cash;j>=1;j--){
    37                 if(j>=price[i])
    38                     dp[j] = max(dp[j],dp[j-price[i]]+price[i]);
    39             }
    40         }
    41 
    42         printf("%d
    ",dp[cash]);
    43     }
    44     return 0;
    45 }
  • 相关阅读:
    golang sql连接池的实现解析
    golang使用rabbitmq正确姿势
    golang使用rabbitmq多个消费者
    golang网关之手动实现反向代理
    golang exec.Command执行脚本 杀死子进程
    exec: "gcc": executable file not found in %PATH%
    golang操作mongodb
    grpc之 普通流 、服务端流、 客户端流 、双向流模式
    grpc-POST提交主订单数据(gateway实现http api)
    grpc之protobuf常用语法速学
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4001903.html
Copyright © 2011-2022 走看看