XiaoE创办了一个小型加工厂,可以来加工n种工件。不过加工这些工件都是原材料的。于是他找到了供应原料的大老板超级大教主(SuperDaLord -> SDL - -!)。
超级大教主告诉XiaoE说,“以咱们的关系,我绝对以最低价进给你原料,然后你把做好的工件拿来,我绝对以最高价收购。不过这事不能声张,不然Bin3、Lilu等人都来找我的话我就吃不消了。咱们控制一下数量吧,我每天早上把每种工件的原料进给你一份,晚上再从你那里收购每种工件各一件。”
由于原料供应领域被超级大教主垄断,XiaoE别无选择(也就是买n种原料各一份,生产加工,卖出n种工件各一个)。而且XiaoE的工厂只有一台机器,加工完一种工件后需要对机器进行改造才能加工另一种工件,这个过程中有一定的成本。现在XiaoE想让自己一天内的收入尽可能的多。收入 = 工件卖出价 - 原料进购价 - 机器改造成本。我们假设XiaoE的工厂在一天内可以完成所有计划的生产和交易。
本题有多组测试数据,每组数据的第1行为两个整数n (n <= 15)和m(1 <= m <= n),以空格分隔,分别表示工厂可以来加工工件的数目与初始状态下机器可以加工的工件。以下n行每行有2个正整数,分别表示对应工件的进购价和卖出价 (均不超过105)。接下来给出一个n*n的矩阵(对称阵),表示机器在生产n个工件的工作状态间转换的改造成本。(100以内的非负整数)
对于每组输入,输出一个整数,表示XiaoE在一天内的最大收入。
3 1 2 4 2 3 2 5 0 1 2 1 0 1 2 1 0
4 刚开始m的意义没用看清楚,想了一个小时,结果却只是裸的状态压缩dp,#include <map> #include <set> #include <stack> #include <queue> #include <cmath> #include <ctime> #include <vector> #include <cstdio> #include <cctype> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; #define INF 0x3f3f3f3f #define inf -0x3f3f3f3f #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mem0(a) memset(a,0,sizeof(a)) #define mem1(a) memset(a,-1,sizeof(a)) #define mem(a, b) memset(a, b, sizeof(a)) typedef long long ll; const int maxn=16; int dp[1<<maxn][maxn]; int mp[16][16]; int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF){ for(int i=0;i<(1<<n);i++){ fill(dp[i],dp[i]+n+1,INF); } int u,v; int ans=0; for(int i=1;i<=n;i++){ scanf("%d%d",&u,&v); ans+=(v-u); } for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&mp[i][j]); dp[0][m-1]=0; for(int s=1;s<(1<<n);s++){ for(int i=0;i<n;i++){ //if(((s>>i)&1)==0) //注意这句话千万不能加 //continue; //i==j这句话也不能加,不然的话例如dp[1][0]=0等无法实现 for(int j=0;j<n;j++){ //if(i==j) //continue; if(((s>>j)&1)==0||dp[s^(1<<j)][i]==INF) continue; dp[s][j]=min(dp[s][j],dp[s^(1<<j)][i]+mp[i][j]); //printf("s is %d i is %d j is %d ",s,i,j); //printf("dp[%d][%d] is %d\n",s,i,dp[s][j]); } } } int ans1=INF; for(int i=0;i<n;i++) ans1=min(ans1,dp[(1<<n)-1][i]); printf("%d\n",ans-ans1); } return 0; }