• POJ 1722 DP


    题意:

    定义一种操作,操作i就是将a[i]-a[i+1]取出进行合并,再加入到a[i]的位置(我自己臆测的题意),进行n-1次操作后,会剩下一个数字。

    给定a[1]~a[n]及目标t(最后剩下的数字),求操作顺序。

    思路:

    相当经典!

    此题相当于在序列之间添加+-两种符号使得答案是t

    最后按照+-号输出就是了

    PS:第一个符号必定是减号!

    View Code
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 
     5 #define N 120
     6 #define WC 10000
     7 
     8 using namespace std;
     9 
    10 int n,t,a[N],pre[N],dp[N][20001];
    11 
    12 void read()
    13 {
    14     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    15 }
    16 
    17 void go()
    18 {
    19     memset(dp,0,sizeof dp);
    20     memset(pre,0,sizeof pre);
    21     dp[1][a[1]+WC]=2;
    22     dp[2][a[1]-a[2]+WC]=1;
    23     for(int i=3;i<=n;i++)
    24         for(int j=0;j<=20000;j++)
    25             if(dp[i-1][j]>0)
    26             {
    27                 if(j+a[i]<=20000) dp[i][j+a[i]]=2;
    28                 if(j-a[i]>=0) dp[i][j-a[i]]=1;
    29             }
    30     for(int i=n,j=t+WC;i>=1;i--)
    31     {
    32         if(dp[i][j]==2)
    33         {
    34             pre[i]=2;
    35             j-=a[i];
    36         }
    37         else if(dp[i][j]==1)
    38         {
    39             pre[i]=1;
    40             j+=a[i];
    41         }
    42     }
    43     int cnt=0;
    44     for(int i=2;i<=n;i++)
    45         if(pre[i]==2) printf("%d\n",i-1-cnt),cnt++;
    46     for(int i=2;i<=n;i++)
    47         if(pre[i]==1) puts("1");
    48 }
    49 
    50 int main()
    51 {
    52     while(scanf("%d%d",&n,&t)!=EOF)
    53     {
    54         read();
    55         go();
    56     }
    57     return 0;
    58 }
    没有人能阻止我前进的步伐,除了我自己!
  • 相关阅读:
    机器学习:特征选择方法简介
    VS快捷键
    非常适用的Sourceinsight插件,提高效率【强力推荐】
    Linux静态库和共享库
    C/C++ 位域知识小结
    __BEGIN_DECLS 和 __END_DECLS
    C语言可变参数va_list
    mac的terminal快捷键
    linux进程、线程与cpu的亲和性(affinity)
    C++ Singleton (单例) 模式最优实现
  • 原文地址:https://www.cnblogs.com/proverbs/p/2711450.html
Copyright © 2020-2023  润新知