zoj3010The Lamp Game(状态压缩+SPFA求最大路)经典

The Lamp Game


Time Limit: 2 Seconds
Memory Limit: 65536 KB



Little Tom likes playing games. Recently he is fond of a game called Lamp Game. The game is like this: at first, there are n lamps on the desk, all of which are lighted and Tom is given an initial score. Each time, Tom selects one lamp and changes its state,
this action will costs little Tom some percent of score. What‘s more, the circuit of the lamps is designed so that, when Tom changes the state of one lamp, some related lamps‘ states will also be changed. The object of this game is to make all lamps
off and make the total lost of score as low as possible. Of course little Tom is not smart enough to solve this problem, so he asks you, a student in ZJU, to help him.

Input

The input contains several test cases. Each case begins with two integers n and m (n<=10,0<m<=100000000), which are the number of lamps and the initial score of Tom. Then n lines follows, each in the format of t n1 n2 ...... nt f (0<=t<n,1<=ni<=n,0<=f<100).
The i-th line means changing the state of the i-th lamp will make t related lamps‘ states changed and the following t integers give the t related lamps (these t numbers will not include i). And changing the state of the i-th lamp will cost Tom f percents of
score. All numbers are integers. Two 0s of n and m signals the end of input.

Output

For each test case, output one line containing the maximum score Tom has when he finished the game successfully. The result should be accurate to 2 decimal places. If Tom cannot finish this game, simply output -1.

Sample Input:

3 100
1 2 50
0 50
1 2 50
0 0

Sample Output

12.50
解题:可以把n个灯看成一个整体状态,因每种状态每次只能翻一个灯,所以有n种转换法,如果我们直接用深搜或广搜那么最坏情况有10^10肯定会超时,那么我们再想因为一个状态经过一次转第i个灯变成为另一个状态,可以看成一条有向边,边权为1-perc[i]/100,也不是转变后的状态剩于score占上一状态的百分比。这样我们把一个状态看成一个点就会联想到最短路算法,想法正确,就是求最大路,那么我们就可以先根据上面所说的去建图,把状态看成一个点,边权就是上述的百分比。这样也就算是完成了这个题。
#include<stdio.h>
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
#define N 1029
typedef struct nn
{
    int to;
    double per;
}TO;
vector<TO>map[N];
double node[N];
void bfs(int st,double m)
{
    queue<int>q;
    int inq[N]={0};
    q.push(st); inq[st]=1; node[st]=m;
    while(!q.empty())
    {
        int p=q.front(); q.pop();
        inq[p]=0;
        for(int j=0;j<map[p].size();j++)
        {
            int i=map[p][j].to;
            if(node[i]<node[p]*map[p][j].per)
            {
                node[i]=node[p]*map[p][j].per;
                if(!inq[i])
                inq[i]=1,q.push(i);
            }
        }
    }
}
double perc[11];
int turn[11];
void buildeMap(int n)
{
    TO p; node[0]=-1;
    for(int i=1;i<(1<<n);i++)
    {
        map[i].clear(); node[i]=-1;
        for(int j=0;j<n;j++)
        {
            p.to=i^turn[j];p.per=(100-perc[j])/100;
            map[i].push_back(p);
        }
    }
}
int main()
{
    int n,t,a;
    double m;
    while(scanf("%d%lf",&n,&m)>0&&(n||m))
    {
        for(int i=0;i<n;i++)
        {
            scanf("%d",&t); turn[i]=1<<i;
            while(t--)
            {
                scanf("%d",&a);a--; turn[i]|=1<<a;
            }
            scanf("%lf",&perc[i]);
        }
        buildeMap(n);
        bfs((1<<n)-1,m);
        if(node[0]>0)printf("%.2lf\n",node[0]);
        else printf("-1\n");
    }
}

zoj3010The Lamp Game(状态压缩+SPFA求最大路)经典

时间: 2024-10-06 17:38:42

zoj3010The Lamp Game(状态压缩+SPFA求最大路)经典的相关文章

hdu 4352 数位dp + 状态压缩

XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2265    Accepted Submission(s): 927 Problem Description #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then careful

Victor and World(spfa+状态压缩dp)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5418 Victor and World Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Others)Total Submission(s): 958    Accepted Submission(s): 431 Problem Description After trying hard fo

HDU3768 Shopping(状态压缩DP+spfa)旅行商问题

Shopping Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 577    Accepted Submission(s): 197 Problem Description You have just moved into a new apartment and have a long list of items you need

POJ2288Islands and Bridges(状态压缩DP,求最大路和走条数)

Islands and Bridges Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 8845   Accepted: 2296 Description Given a map of islands and bridges that connect these islands, a Hamilton path, as we all know, is a path along the bridges such that i

HDU 4085 Peach Blossom Spring 斯坦纳树 状态压缩DP+SPFA

状态压缩dp+spfa解斯坦纳树 枚举子树的形态 dp[i][j] = min(dp[i][j], dp[i][k]+dp[i][l]) 其中k和l是对j的一个划分 按照边进行松弛 dp[i][j] = min(dp[i][j], dp[i'][j]+w[i][j])其中i和i'之间有边相连 #include <cstdio> #include <cstring> #include <queue> using namespace std; const int maxn

ACM学习历程—HDU1584 蜘蛛牌(动态规划 &amp;&amp; 状态压缩)

Description 蜘蛛牌是windows xp操作系统自带的一款纸牌游戏,游戏规则是这样的:只能将牌拖到比她大一的牌上面(A最小,K最大),如果拖动的牌上有按顺序排好的牌时,那么这些牌也跟着一起移动,游戏的目的是将所有的牌按同一花色从小到大排好,为了简单起见,我们的游戏只有同一花色的10张牌,从A到10,且随机的在一行上展开,编号从1到10,把第i号上的牌移到第j号牌上,移动距离为abs(i-j),现在你要做的是求出完成游戏的最小移动距离. Input 第一个输入数据是T,表示数据的组数.

HDU 5418 Victor and World (状态压缩dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5418 题目大意:有n个结点m条边(有边权)组成的一张连通图(n <16, m<100000).求从第一个点出发,经过每个点至少一次后回到原点的最小路径边权和. 分析:发现我还真是菜. n<16,很明显的状态压缩标记,先将所有点的编号减去1,使其从0开始编号.dp[i][j]表示从0号点出发,当前状态为i (二进制位为1表示对应点已走过,否则没走过), 当前位置为 j,  回到原点的最小代价,

软件补丁问题(状态压缩 最短路)

先状态压缩,再求费用流,但耗内存太大,改变存边方式降低内存使用. 直接求最短路即可 //http://www.cnblogs.com/IMGavin/ #include <iostream> #include <stdio.h> #include <cstdlib> #include <cstring> #include <queue> #include <vector> #include <map> #include &

uva 11280 状态压缩+最短路

题意:坐飞机从 a 地到 b 地 ,在最多停留s次时 , 最小花费是多少? 在题目给出的地点 , 是按从远到近给出的 , 并且给出的航班中 , 不会有从远地点到近地点的航班. 因此从这可以看出 , 题目给的图是一个DAG图 , 那么我们就能用toposort来找最短路. 注意: 会有重边 解法: 构造一个数组 d[i][j]  , 表示从开始点 s  到点 i , 在停留 j 次时的最小花费. 然后我们再求出这个图的toposort , 再求这个每一个点和其相邻点的距离. 代码: #includ