洛谷4

补题
这样想这道题目,对于每一个花盆,有选与不选两种操作,这不就是01背包吗。唯一的区别在于必须按照种类顺序去选花盆,每一种花盆的个数是有限制的。因此稍微改进01背包即可求解。
这位佬的博客讲的十分详细了。直接上代码了:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 105, mod = 1000007;
int n, m, f[maxn], sum[maxn], a[maxn];
int main(){

  cin >> n >> m;
  for (int i = 1;i<=n;i++)cin>>a[i];
  f[0] = 1;
  for (int i = 0; i <= m;i++)
    sum[i] = 1;
  for (int i = 1; i <= n;i++){//外层枚举种类
    for (int j = m; j >= 1;j--){//内层循环直接01背包
      int t = j - min(a[i], j)-1;
      if(t<0)
        f[j] = (f[j] + sum[j - 1]) % mod;
      else
        f[j] = (f[j] + sum[j - 1] - sum[t] + mod) % mod;
    }
    for (int j = 1;j<=m;j++)
      sum[j] = (sum[j - 1] + f[j]) % mod;
  }
  cout << f[m] << endl;
  return 0;
}
https://www.luogu.com.cn/problem/P1090
简单的算法题目,合并果子消耗的最小值显然等于,,,看错了,以为是区间dp,,,,结果一看就更简单了。。。直接合并数量小的,可以证明这样总体力最小。就一个贪心。。。。但是,
还有很多用排序,但是根本不测试就往上发那种一定会TLE代码的沙雕
于是发现multiset的插入删除只有log n的级别,那么我们的时间复杂度就一定是o(n)
#include <bits/stdc++.h>
using namespace std;
int main(){
  multiset<int> heap;
  int n;
  cin>>n;
  int x;
  for (int i = 0; i < n;i++){
    cin>>x;
    heap.insert(x);
  }
  int sum1=0, sum=0;
  for (int i = 1; i <= n - 1;i++){
    sum1 = *heap.begin();
    heap.erase(heap.begin());
    sum1 += *heap.begin();
    heap.erase(heap.begin());
    sum += sum1;
    heap.insert(sum1);
  }
  cout << sum << endl;
  return 0;
}
https://www.luogu.com.cn/problem/solution/P1091
从左到右和从右到左分别找就行
P1103书本整理,不是很理解https://www.luogu.com.cn/blog/user8742/solution-p1103


全部评论

相关推荐

评论
点赞
收藏
分享
牛客网
牛客企业服务