UVa 10498 Happiness! (线性规划)
题意
将N种食品分给m个参赛选手,一个单位的某食品给某个选手一定满足度,每个选手有一个最大满足度。为了避免浪费,分给每一个选手的食品都不超越选手的满足度。已知的各种食品的单价,求最多可以花的钱。
思路
标准的线性规划---直接求即可……目前只会用用模板,还没搞清楚单纯性算法……
代码
[cpp]
/**
Simplex C(n+m)(n)
maximize:
c[1]*x[1]+c[2]*x[2]+...+c[n]*x[n]+ans
subject to
a[1,1]*x[1]+a[1,2]*x[2]+...a[1,n]*x[n] <= rhs[1]
a[2,1]*x[1]+a[2,2]*x[2]+...a[2,n]*x[n] <= rhs[2]
......
a[m,1]*x[1]+a[m,2]*x[2]+...a[m,n]*x[n] <= rhs[m]
限制:
传入的矩阵必须是标准形式的, 即目标函数要最大化;约束不等式均为<= ;xi为非负数(>=0).
simplex返回参数:
OPTIMAL 有唯一最优解
UNBOUNDED 最优值无边界
FEASIBLE 有可行解
INFEASIBLE 无解
n为元素个数,m为约束个数
线性规划:
max c[]*x;
a[][]<=rhs[];
ans即为结果,x[]为一组解(最优解or可行解)
**/
const double eps = 1e-8;
const double inf = 1e15;
#define OPTIMAL -1 //表示有唯一的最优基本可行解
#define UNBOUNDED -2 //表示目标函数的最大值无边界
#define FEASIBLE -3 //表示有可行解
#define INFEASIBLE -4 //表示无解
#define PIVOT_OK 1 //还可以松弛
#define maxn 1000
struct LinearProgramming{
int basic[maxn], row[maxn], col[maxn];
double c0[maxn];
double dcmp(double x){
if (x > eps) return 1;
else if (x < -eps) return -1;
return 0;
}
void init(int n, int m, double c[], double a[maxn][maxn], double rhs[], double &ans) { //初始化
for(int i = 0; i <= n+m; i++) {
for(int j = 0; j <= n+m; j++) a[i][j]=0;
basic[i]=0; row[i]=0; col[i]=0;
c[i]=0; rhs[i]=0;
}
ans=0;
}
//转轴操作
int Pivot(int n, int m, double c[], double a[maxn][maxn], double rhs[], int &i, int &j){
double min = inf;
int k = -1;
for (j = 0; j <= n; j ++)
if (!basic[j] && dcmp(c[j]) > 0)
if (k < 0 || dcmp(c[j] - c[k]) > 0) k = j;
j = k;
if (k < 0) return OPTIMAL;
for (k = -1, i = 1; i <= m; i ++) if (dcmp(a[i][j]) > 0)
if (dcmp(rhs[i] / a[i][j] - min) < 0){ min = rhs[i]/a[i][j]; k = i; }
i = k;
if (k < 0) return UNBOUNDED;
else return PIVOT_OK;
}
int PhaseII(int n, int m, double c[], double a[maxn][maxn], double rhs[], double &ans, int PivotIndex){
int i, j, k, l; double tmp;
while(k = Pivot(n, m, c, a, rhs, i, j), k == PIVOT_OK || PivotIndex){
if (PivotIndex){ i = PivotIndex; j = PivotIndex = 0; }
basic[row[i]] = 0; col[row[i]] = 0; basic[j] = 1; col[j] = i; row[i] = j;
tmp = a[i][j];
for (k = 0; k <= n; k ++) a[i][k] /= tmp;
rhs[i] /= tmp;
for (k = 1; k <= m; k ++)
if (k != i && dcmp(a[k][j])){
tmp = -a[k][j];
for (l = 0; l <= n; l ++) a[k][l] += tmp*a[i][l];
rhs[k] += tmp*rhs[i];
}
tmp = -c[j];
for (l = 0; l <= n; l ++) c[l] += a[i][l]*tmp;
ans -= tmp * rhs[i];
}
return k;
}
int PhaseI(int n, int m, double c[], double a[maxn][maxn], double rhs[], double &ans){
int i, j, k = -1;
double tmp, min = 0, ans0 = 0;
for (i = 1; i <= m; i ++)
if (dcmp(rhs[i]-min) < 0){min = rhs[i]; k = i;}
if (k < 0) return FEASIBLE;
for (i = 1; i <= m; i ++) a[i][0] = -1;
for (j = 1; j <= n; j ++) c0[j] = 0;
c0[0] = -1;
PhaseII(n, m, c0, a, rhs, ans0, k);
if (dcmp(ans0) < 0) return INFEASIBLE;
for (i = 1; i <= m; i ++) a[i][0] = 0;
for (j = 1; j <= n; j ++)
if (dcmp(c[j]) && basic[j]){
tmp = c[j];
ans += rhs[col[j]] * tmp;
for (i = 0; i <= n; i ++) c[i] -= tmp*a[col[j]][i];
}
return FEASIBLE;
}
//standard form
//n:原变量个数 m:原约束条件个数
//c:目标函数系数向量-[1~n],c[0] = 0;
//a:约束条件系数矩阵-[1~m][1~n] rhs:约束条件不等式右边常数列向量-[1~m]
//ans:最优值 x:最优解||可行解向量-[1~n]
int simplex(int n, int m, double c[], double a[maxn][maxn], double rhs[], double &ans, double x[]){
int i, j, k;
//标准形式变松弛形式
for (i = 1; i <= m; i ++){
for (j = n+1; j <= n+m; j ++) a[i][j] = 0;
a[i][n+i] = 1; a[i][0] = 0;
row[i] = n+i; col[n+i] = i;
}
k = PhaseI(n+m, m, c, a, rhs, ans);
if (k == INFEASIBLE) return k;
k = PhaseII(n+m, m, c, a, rhs, ans, 0);
for (j = 0; j <= n+m; j ++) x[j] = 0;
for (i = 1; i <= m; i ++) x[row[i]] = rhs[i];
return k;
}
}ps; //Primal Simplex
int n,m;
double c[maxn], ans, a[maxn][maxn], b[maxn], x[maxn];
int main(){
//freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
while(scanf("%d %d", &n, &m) != EOF){
double ans;
ps.init(n, m, c, a, b, ans);
for (int i = 1; i <= n; i ++)
scanf("%lf", &c[i]);
for (int i = 1; i <= m; i ++){
for (int j = 1; j <= n; j ++){
scanf("%lf", &a[i][j]);
}
scanf("%lf", &b[i]);
}
ps.simplex(n,m,c,a,b,ans,x);
printf("Nasa can spend %.0f taka.\n", ceil(m*ans));
}
return 0;
}
[/cpp]
UVa 10498 Happiness! (线性规划)的更多相关文章
- UVA 10498 Happiness(线性规划-单纯形)
Description Prof. Kaykobad has given Nasa the duty of buying some food for the ACM contestents. Nasa ...
- 数学(线性规划):UVAoj 10498 Happiness
Problem GHappiness! Input: standard inputOutput: standard outputTime Limit: 3 seconds Prof. Kaykobad ...
- 【Uva 10498】满意值
Description Kaykobad教授把为ACM选手买饭的任务交给了Nasa.Nasa决定买n种不同的食物.然后他询问了m名选手对每种食物的需求量.选手们当然不会给出任何符合逻辑的回答,他们只是 ...
- 算法模板の数学&数论
1.求逆元 int inv(int a) { ) ; return (MOD - MOD / a) * inv(MOD % a); } 2.线性筛法 bool isPrime[MAXN]; int l ...
- UVA11722概率问题之线性规划
链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&am ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- uva 1354 Mobile Computing ——yhx
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGcAAANuCAYAAAC7f2QuAAAgAElEQVR4nOy9XUhjWbo3vu72RRgkF5
- UVA 10564 Paths through the Hourglass[DP 打印]
UVA - 10564 Paths through the Hourglass 题意: 要求从第一层走到最下面一层,只能往左下或右下走 问有多少条路径之和刚好等于S? 如果有的话,输出字典序最小的路径 ...
- UVA 11404 Palindromic Subsequence[DP LCS 打印]
UVA - 11404 Palindromic Subsequence 题意:一个字符串,删去0个或多个字符,输出字典序最小且最长的回文字符串 不要求路径区间DP都可以做 然而要字典序最小 倒过来求L ...
随机推荐
- JQuery拾遗
1.关于JQuery的animate,可以操作background么? 答:如果是单纯的JQuery不可以,需要引入JQuery的ui核心库.否则只支持宽高.透明度.上下左右位置的变化. 2.能否说一 ...
- poj 1678 I Love this Game!
思路:这题和博弈论的关系不大,主要是DP.记忆化搜索即可!!! 取的数一定是大于0的,所以将负数去掉!! 代码如下: #include<iostream> #include<cstd ...
- C#反射Assembly 详细说明
1.对C#反射机制的理解2.概念理解后,必须找到方法去完成,给出管理的主要语法3.最终给出实用的例子,反射出来dll中的方法 反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等 ...
- 李洪强iOS开发之OC点语法和变量作用域
OC点语法和变量作用域 一.点语法 (一)认识点语法 声明一个Person类: 1 #import <Foundation/Foundation.h> 2 3 @interface Per ...
- unity HideInInspector 默认值 坑 记录 bug
1: 如果 一个public字段 刚开始有默认值,然后你你觉得这个值不应该给别人看设置为HideInInspector 后,你再在代码里面调整这个默认属性的值,这个时候代码里面调整的值无效. ...
- PHP 反射机制Reflection
简介 PHP Reflection API是PHP5才有的新功能,它是用来导出或提取出关于类.方法.属性.参数等的详细信息,包括注释. class Reflection { } interface R ...
- 深入理解MVC与MVP
http://www.cnblogs.com/seaky/archive/2011/04/06/1982533.html 在深入分析MVC和MVP之前,我们有必要回顾下经典的三层架构.分层是计算机学科 ...
- STL:string 大小(Size)和容量(Capacity)
strings存在三种“大小”: 1.size()和length() 返回string中现在的字符个数.上述两个函数等效. 成员函数empty()用来检验字符数是否为0,亦即字符串是否为空.你应该优先 ...
- CentOS下支持exFAT与NTFS
exFAT: 1.下载fuse-exfat支持软件: exfat支持是通过fuse模块的方式支持的,其项目地址是: https://code.google.com/p/exfat/ ,当前版本是:1. ...
- Android 非Activity类引用getResources()方法问题的解决方法
在进行Android开发的过程中,在一个非Activity类(此处假设类名为MyNewClass)中引用了getResources()方法,如下: Bitmap bmp = BitmapFactory ...