EOJ:ACM Coalition

ACM Coalition

Time Limit: 1000MS Memory Limit: 65536K
Total Submits: 30 Accepted: 6

Description

In the recent parliament election, none of the parties have vast majority of seats, so there should be a coalition to select the members of the Management Board, which are one speaker, two deputy speakers and six secretaries. The board has a special voting system: the speaker has 25 votes, deputy speakers have 8 votes and each secretary has 1 vote.

ACM party decides to take a commanding role and shape the coalition, but they are m seats short to have a majority.
They know the number of seats that every other party has taken. To participate in the coalition, each party demands its share from the Management Board in the form of a triplet (a, b, c) where a, b, and c are the number of speakers, deputy speakers, and secretaries that are expected to be selected from that party. For example, if the party BDN has a demand of (1, 1, 2), it expects that the speaker, one of the deputy speakers, and two of the secretaries are selected from BDN. A party may have multiple demands, meaning that the party accepts to participate in the coalition if one of its demands is satisfied.

Knowing the demands of all other parties, ACM wants to know how powerful it can be in Management Board. This means that ACM wants to maximize its number of votes while forming a coalition with other parties such that it overcomes its shortage of m seats.

 

Input

The input contains multiple test cases. Each test case starts with a line containing two integers n and m. The integer n is the number of line parties (n ≤ 50) and m is the number of seats ACM party needs. The next n lines contain other parties’ information, each beginning with number of seats the party has, followed by a colon, a space, and a list of demands for that party. The list of demands is in the form of triplets (a, b, c) where 0 ≤ a ≤ 1, 0 ≤ b ≤ 2, and 0 ≤ c ≤ 6. The triplets are separated by the string “ or ” and are terminated with a semicolon in the end (see the sample input).
The input is terminated with a line containing 0 0.

 

Output

For each test case, write a single line containing three integers, which represent speaker, deputy speaker and secretaries which ACM party can have in the coalition to have maximum votes in board’s voting system.

 

Sample Input

3 4
1: (0,0,0);
2: (1,2,0);
3: (1,0,5) or (1,2,0) or (0,2,6);
1 0
1: (1,1,1);
1 1
1: (1,1,1);
4 6
6: (1,0,0) or (1,2,6);
2: (0,2,0);
2: (0,0,3);
2: (0,0,3);
0 0 

 

Sample Output

1 0 0
1 2 6
0 1 5
1 0 0
原题地址:http://www.cn210.com/onlinejudge/problemshow.php?pro_id=222
_________________________________________________________________________________________________________
题解:

总觉得题目描述肯定有问题。他肯定把SEAT和VOTE搞混了。

分组背包,有三个价格。

for 所有的组k

    for v=V..0

        for 所有的i属于组k

            f[v]=max{f[v],f[v-c[i]]+w[i]}

要注意一个问题,如果用三维的数组记录的话,要去掉重复的情况,数据中有一个组中有多个物品为(0,0,0)。

这样三维的数组会重复使用该物品而违背了一组中只能取一个物品。若用四维的数组就不会出现。

 

 

 

代码
1 #include<stdio.h>
2 #include<memory.h>
3  #define oo 0xfffffff
4  struct node
5 {
6 int a,b,c;
7 }w[900];
8 int v[900],dp[900][2][3][7],head[52];
9 int i,j,k,l,p,n,m,t,temp,a,b,c;
10 char ch;
11 int max(int a,int b)
12 {
13 if (a>b) return a;
14 return b;
15 }
16 void init()
17 {
18 t=0;
19 memset(head,0,sizeof(head));
20 memset(v,0,sizeof(v));
21 memset(w,0,sizeof(w));
22 for (i=1;i<=n;i++)
23 {
24 head[i]=t+1;
25 scanf("%d: ",&temp);
26 ch=getchar();
27 while (ch!=';')
28 {
29 if (ch=='(')
30 {
31 t++;
32 scanf("%d,%d,%d)",&w[t].a,&w[t].b,&w[t].c);
33 v[t]=temp;
34 }
35 ch=getchar();
36 }
37 }
38 head[n+1]=t+1;
39 }
40 void solve()
41 {
42 for (i=0;i<=n;i++)
43 for (j=1;j<=1;j++)
44 for (k=1;k<=2;k++)
45 for (l=1;l<=6;l++)
46 dp[i][j][k][l]=-oo;
47 for (i=0;i<=n;i++)
48 dp[i][0][0][0]=0;
49 for (i=1;i<=n;i++)
50 for (k=0;k<=1;k++)
51 for (l=0;l<=2;l++)
52 for (p=0;p<=6;p++)
53 {
54 dp[i][k][l][p]=dp[i-1][k][l][p];
55 for (j=head[i];j<=t&&j<head[i+1];j++)
56 if (k-w[j].a>=0&&l-w[j].b>=0&&p-w[j].c>=0)
57 dp[i][k][l][p]=max(dp[i][k][l][p],dp[i-1][k-w[j].a][l-w[j].b][p-w[j].c]+v[j]);
58 }
59 a=0;
60 b=0;
61 c=0;
62 for (i=0;i<=n;i++)
63 for (j=0;j<=1;j++)
64 for (k=0;k<=2;k++)
65 for (l=0;l<=6;l++)
66 if(dp[i][j][k][l]>=m)
67 if (1-j>a||(1-j==a&&2-k>b)||(1-j==a&&2-k==b&&6-l>c))
68 {
69 a=1-j;
70 b=2-k;
71 c=6-l;
72 }
73 printf("%d %d %d\n",a,b,c);
74
75 }
76 int main()
77 {
78 scanf("%d%d",&n,&m);
79 while (1)
80 {
81 if (n==0&&m==0) break;
82 init();
83 solve();
84 scanf("%d%d",&n,&m);
85 }
86 return 0;
87 }
88

 

posted on 2010-07-28 14:38  风也轻云也淡  阅读(246)  评论(0编辑  收藏  举报