A---染色
签到题,设最终颜色为x,一次操作就需要把一个不是x的点变为x,所以最终颜色为x时需要操作 总结点个数-颜色为x的节点个数,然后枚举所有颜色就行了
1 #include <iostream> 2 #include <string.h> 3 #include <cstdio> 4 #include <vector> 5 #include <map> 6 #include <math.h> 7 #include <string> 8 #include <algorithm> 9 #include <time.h> 10 11 #define SIGMA_SIZE 26 12 #define lson rt<<1 13 #define rson rt<<1|1 14 #define lowbit(x) (x&-x) 15 #define foe(i, a, b) for(int i=a; i<=b; i++) 16 #define fo(i, a, b) for(int i = a; i < b; i++); 17 #pragma warning ( disable : 4996 ) 18 19 using namespace std; 20 typedef long long LL; 21 inline LL LMax(LL a,LL b) { return a>b?a:b; } 22 inline LL LMin(LL a,LL b) { return a>b?b:a; } 23 inline LL lgcd( LL a, LL b ) { return b==0?a:lgcd(b,a%b); } 24 inline LL llcm( LL a, LL b ) { return a/lgcd(a,b)*b; } //a*b = gcd*lcm 25 inline int Max(int a,int b) { return a>b?a:b; } 26 inline int Min(int a,int b) { return a>b?b:a; } 27 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); } 28 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; } //a*b = gcd*lcm 29 const LL INF = 0x3f3f3f3f3f3f3f3f; 30 const LL mod = 1000000007; 31 const double eps = 1e-8; 32 const int inf = 0x3f3f3f3f; 33 const int maxk = 1e6+5; 34 const int maxn = 1e5+5; 35 36 int N, ct; 37 int cnt[maxn]; 38 LL num[maxn]; 39 LL all; 40 struct col { 41 int id; 42 LL val; 43 col() {} 44 }color[maxn]; 45 46 bool cmp(const col& a, const col& b) 47 { 48 return a.val < b.val; 49 } 50 51 void read() 52 { 53 memset(cnt, 0, sizeof(cnt)); 54 memset(num, 0, sizeof(num)); 55 all = 0; 56 57 foe(i, 1, N) 58 { 59 scanf("%lld", &color[i].val); 60 all += color[i].val; 61 color[i].id = i; 62 } 63 sort(color+1, color+1+N, cmp); 64 65 int x, y; 66 foe(i, 1, N-1) 67 { 68 scanf("%d %d", &x, &y); 69 } 70 } 71 72 int main() 73 { 74 while (~scanf("%d", &N)) 75 { 76 read(); 77 78 LL tmp = color[1].val; 79 num[1] = color[1].val; 80 cnt[1] = 1; 81 ct = 1; 82 foe(i, 2, N) 83 { 84 if (color[i].val == tmp) 85 { 86 cnt[ct]++; 87 continue; 88 } 89 90 tmp = color[i].val; 91 num[++ct] = tmp; 92 cnt[ct] = 1; 93 } 94 95 LL mmin = INF; 96 foe(i, 1, ct) 97 { 98 tmp = all; 99 tmp -= num[i]*cnt[i]; 100 if (tmp >= mmin) continue; 101 tmp += (N-cnt[i])*num[i]; 102 mmin = LMin(tmp, mmin); 103 } 104 printf("%lld ", mmin); 105 } 106 return 0; 107 }
B---背包
我觉得这道题有点问题...先按价值排个序,然后考虑中位数两边最小的体积是多少呢,用优先队列从1~N扫一遍,再从N~1扫一遍,就可以记录下每个点往左和往右的所有物品中,取体积最小的M/2个物品的体积总和是多少,分别记为sum1[i],sum2[i],然后分奇偶讨论一下就行了(还是觉得数据有点问题,)
1 #include <iostream> 2 #include <string.h> 3 #include <cstdio> 4 #include <vector> 5 #include <map> 6 #include <queue> 7 #include <math.h> 8 #include <string> 9 #include <algorithm> 10 #include <time.h> 11 12 #define SIGMA_SIZE 26 13 #define lson rt<<1 14 #define rson rt<<1|1 15 #define lowbit(x) (x&-x) 16 #define foe(i, a, b) for(int i=a; i<=b; i++) 17 #define fo(i, a, b) for(int i = a; i < b; i++); 18 #pragma warning ( disable : 4996 ) 19 20 using namespace std; 21 typedef long long LL; 22 inline LL LMax(LL a, LL b) { return a>b ? a : b; } 23 inline LL LMin(LL a, LL b) { return a>b ? b : a; } 24 inline LL lgcd(LL a, LL b) { return b == 0 ? a : lgcd(b, a%b); } 25 inline LL llcm(LL a, LL b) { return a / lgcd(a, b)*b; } //a*b = gcd*lcm 26 inline int Max(int a, int b) { return a>b ? a : b; } 27 inline int Min(int a, int b) { return a>b ? b : a; } 28 inline int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b); } 29 inline int lcm(int a, int b) { return a / gcd(a, b)*b; } //a*b = gcd*lcm 30 const LL INF = 0x3f3f3f3f3f3f3f3f; 31 const LL mod = 1000000007; 32 const double eps = 1e-8; 33 const int inf = 0x3f3f3f3f; 34 const int maxk = 1e6 + 5; 35 const int maxn = 1e5 + 5; 36 37 //优先队列默认从大到排列 38 priority_queue<LL> qq; 39 int V, N, M; 40 LL sum; 41 LL sum1[maxn], sum2[maxn]; 42 struct node { 43 LL val, cost; 44 }pp[maxn]; 45 46 bool cmp(const node& a, const node& b) 47 { 48 return a.val == b.val ? a.cost<b.cost : a.val<b.val; 49 } 50 51 void init() 52 { 53 foe(i, 1, N) 54 scanf("%lld %lld", &pp[i].val, &pp[i].cost); 55 sort(pp + 1, pp + 1 + N, cmp); 56 } 57 58 void solve(int i, int mid, LL ss[]) 59 { 60 ss[i] = sum; 61 62 sum += pp[i].cost; 63 qq.push(pp[i].cost); 64 65 if (qq.size() > mid) { 66 sum -= qq.top(); 67 qq.pop(); 68 } 69 } 70 71 int main() 72 { 73 cin >> V >> N >> M; 74 75 init(); 76 77 sum = 0; 78 int mid = M / 2; 79 //正向扫一遍 80 for (int i = 1; i <= N; i++) 81 solve(i, mid, sum1); 82 83 sum = 0; while (!qq.empty()) qq.pop(); 84 //反向扫一遍 85 for (int i = N; i >= 1; i--) 86 solve(i, mid, sum2); 87 88 89 if (M % 2) 90 { 91 for (int i = N - mid; i >= mid + 1; i--) 92 if (sum1[i] + sum2[i] + pp[i].cost <= V) 93 { 94 printf("%lld ", pp[i].val); 95 break; 96 } 97 } 98 else 99 { 100 for (int i = N - mid + 1; i >= mid; i--) 101 if (sum1[i] + sum2[i - 1] <= V) 102 { 103 printf("%lld ", (pp[i].val + pp[i - 1].val) / 2); 104 break; 105 } 106 107 } 108 109 110 return 0; 111 }