• BestCoder Round #91 1001 Lotus and Characters


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6011

    题意:

    Lotus有nn种字母,给出每种字母的价值以及每种字母的个数限制,她想构造一个任意长度的串。
    定义串的价值为:第1位字母的价值*1+第2位字母的价值*2+第3位字母的价值*3……
    求Lotus能构造出的串的最大价值。(可以构造空串,因此答案肯定geq 00)

    分析:

    做这个题目的时候,第一感觉回溯算了,不用想,肯定T了。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 int n;
     6 int val[30];
     7 int cnt[30];
     8 int len;
     9 
    10 int dfs(int cur)
    11 {
    12     int ans = 0;
    13     if(cur>=len+1) return 0;
    14     else
    15     {
    16         for(int i=0; i<n; i++)
    17         {
    18             if(cnt[i]>0)
    19             {
    20                 cnt[i]--;
    21                 ans = max(ans,(cur+1)*val[i]+dfs(cur+1));
    22                 cnt[i]++;
    23             }
    24         }
    25     }
    26     return ans;
    27 }
    28 
    29 int main()
    30 {
    31     int t;
    32     scanf("%d",&t);
    33 
    34     while(t--)
    35     {
    36         scanf("%d",&n);
    37         len = 0;
    38         for(int i=0; i<n; i++)
    39         {
    40             scanf("%d%d",&val[i],&cnt[i]);
    41             len+=cnt[i];
    42         }
    43 
    44         printf("%d
    ",dfs(0));
    45     }
    46     return 0;
    47 }

    后来想DP,直觉告诉我,正权值的放后面。每次计算后面的数值,又不知道前面有多少位,怎么解决这个问题呢?

    就类似于前缀和,写一个后缀和,之前的位数不确定,怎么解决呢?

    Ans[i] = Ans[i+1] + sum[i+1] +v[i];

    状态转移就是多加了一遍后缀和,和首位。最后找一下最好的切割点。

    其实这个切割点也可以从后往前找。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     int t;
     8     scanf("%d",&t);
     9     while(t--) {
    10         int n;
    11         scanf("%d",&n);
    12 
    13         vector<int> v;
    14 
    15         for(int i=0;i<n;i++) {
    16             int val,cnt;
    17             scanf("%d%d",&val,&cnt);
    18             for(int i=0;i<cnt;i++) {
    19                 v.push_back(val);
    20             }
    21         }
    22 
    23         sort(v.begin(),v.end());
    24 
    25         int len = v.size();
    26 
    27         int Ans[10010];
    28         int sum[10010];
    29 
    30         memset(Ans,0,sizeof(Ans));
    31         memset(sum,0,sizeof(sum));
    32 
    33         for(int i=len-1;i>=0;i--) {
    34             sum[i] = sum[i+1] + v[i];
    35         }
    36 
    37         for(int i=len-1;i>=0;i--) {
    38             Ans[i] = Ans[i+1] + sum[i+1] + v[i];
    39         }
    40 
    41         int ans = 0;
    42 
    43         //for(int i=0;i<len;i++) {
    44         //    ans = max(ans,Ans[i]);
    45         //}
    46 
    47 
    48         for(int i=len-1;i>=0;i--) {
    49             if(ans<Ans[i])
    50                 ans = Ans[i];
    51             else break;
    52         }
    53 
    54         printf("%d
    ",ans);
    55     }
    56 
    57     return 0;
    58 }
  • 相关阅读:
    Java实现 LeetCode 61 旋转链表
    Java实现 LeetCode 60 第k个排列
    Java实现 LeetCode 60 第k个排列
    Java实现 LeetCode 60 第k个排列
    Java实现 LeetCode 59 螺旋矩阵 II
    VC 2005 解决方案的目录结构设置和管理
    Visual C++ 设置适合自己的解决方案目录结构
    瑞蓝RL-NDVM-A16网络视频解码器 视频上墙解决方案专家--数字视频解码矩阵
    为什么类的定义中不能包含其自身类型,但是能包含其自身的指针或引用类型
    C++模板使用介绍
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6339982.html
Copyright © 2020-2023  润新知