码迷,mamicode.com
首页 > 其他好文 > 详细

转移顺序的艺术 luogu4394 + lougu2966

时间:2018-10-18 21:55:19      阅读:122      评论:0      收藏:0      [点我收藏+]

标签:algorithm   其它   turn   include   允许   set   自己的   type   har   

lougu4394:

N个政党要组成一个联合内阁,每个党都有自己的席位数.

现在希望你找出一种方案,你选中的党的席位数要大于总数的一半,并且联合内阁的席位数越多越好.

对于一个联合内阁,如果某个政党退出后,其它党的席位仍大于总数的一半,则这个政党被称为是多余的,这是不允许的.

将最后一个限制转化成,去掉所选的最小的,剩下的小于等于总数的一半

根据上面的转化,将a[i],从大到小排序考虑,01背包即可

code:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int MAXX = 330;

int sum, n;
int a[MAXX];
bool f[310][100100];
inline bool cmp (int a, int b) {
  return a > b; 
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &a[i]);
    sum += a[i];
  }
  sort(a + 1, a + n + 1, cmp);
  f[0][0] = 1;
  for (int i = 1; i <= n; ++i) {
    for (int j = 0; j <= sum; ++j) {
      f[i][j] |= f[i - 1][j];
      if(j - a[i] >= 0 && j - a[i] <= (sum / 2))f[i][j] |= f[i - 1][j - a[i]];
    }
  }
  int ans = 0; 
  for (int i = sum / 2; i <= sum ; ++i) if (f[n][i]) ans = i;
  printf("%d", ans);
  return 0;
}

luogu2966
在无向连通图中,有点权,有边权,给出多次询问起点和终点的(路径边权和 + 路径上最大值)的最小值
根据floyd,f[k][i][j]表示从i到j,经过的编号<=k,的最短路,其实k的顺序没有关系,我们不妨按照点权从小打到大排序抉择,当前的k一定是路径上的最大点(不包括i,j)

code:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cctype>

using namespace std;

const int MAXX = 300;

struct node
{
  int id, val;
  bool operator < (const node & a) const {
    return val < a.val;
  }
}pot[MAXX];
int dis[MAXX][MAXX], ans[MAXX][MAXX], mp[MAXX][MAXX], pm[MAXX];
int n, m, q;
inline int rd() {
  int x = 0; bool f = 0;
  char c = getchar();
  while (!isdigit(c)) {
    if (c == ‘-‘) f = 1;
    c =getchar();
  }  
  while (isdigit(c)) {
    x = (x << 1) + (x << 3) + (c ^ 48);
    c = getchar();
  }
  return f ? -x : x;
}
int main() {
  n = rd(); m = rd(); q = rd();
  memset(dis, 0x3f, sizeof(dis));
  memset(ans, 0x3f, sizeof(ans));
  memset(mp, 0x3f, sizeof(mp));
  for (int i = 1; i <= n; ++i) {
    dis[i][i] = 0x3f3f3f3f;
    pot[i].id = i;
    pot[i].val = rd();
    pm[i] = pot[i].val;
  }
  sort(pot + 1, pot + 1 + n);
  for (int i = 1; i <= m; ++i) {
    int x, y, z;
    x = rd(); y = rd(); z = rd();
    mp[x][y] = mp[y][x] = min(min(mp[x][y], mp[y][x]), z);
    dis[x][y] = dis[y][x] = min(dis[x][y], min(dis[y][x], mp[x][y]));
  }
  for (int k = 1; k <= n; ++k) {
    for (int i = 1; i <= n; ++i) {
      for (int j = 1; j <= n; ++j) {
        dis[i][j] = min (dis[i][j], dis[i][pot[k].id] + dis[pot[k].id][j]);
        ans[i][j] = min (ans[i][j], dis[i][j] + max(max( pm[i], pm[j] ), pot[k].val) );
      }
    }
  } 
  while (q--) {
    int u, v;
    u = rd(); v =rd();
    printf("%d\n",min(ans[u][v], ans[v][u]));
  }
  return 0;
}

转移顺序的艺术 luogu4394 + lougu2966

标签:algorithm   其它   turn   include   允许   set   自己的   type   har   

原文地址:https://www.cnblogs.com/ARTlover/p/9813127.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!