不等式求解
- 总时间限制:
- 1000ms
- 内存限制:
- 32768kB
- 描述
有关于变元x1,x2,x3…xn的不等式: k1x1+ k2x2+ k3x3+ … + knxn<= y. 其中ki, y都是正整数
求所有的非负整数解
- 输入
- 输入文件包括两行
第一行是n, 1<=n<=7
第二行包含n+1个用空格分隔的正整数, 分别表示k1, k2…kn, y
- 输出
- 输出文件一行一组解, 每一行有n个用空格分隔的非负整数, 分别表示这组解的x1,x2…xn
所有的解按照x1为第一关键字, x2为第二关键字…从小到大排序
- 样例输入
2 1 2 3
- 样例输出
0 0 0 1 1 0 1 1 2 0 3 0
- 提示
- 不等式中的所有整数均小于30
#include<iostream>
#include<cstdio>
#define N 10
using namespace std;
int n, y, tsum = 0;
int ans[N] = {};
int a[N] = {};
void retrack( int i ){
int k;
if( i == n ){
for( k = 0; k < n; ++k )
printf( "%d ", ans[k]);
//cout << ans[k] << " ";
printf("\n");
return;
}
int l = y / a[i];
for( k = 0; k <= l; ++k ){
int t = k*a[i];
if( tsum + t <= y && tsum + t >= 0){
tsum += t;
ans[i] = k;
retrack(i+1);
tsum -= t;
}else
break;
}
}
int main(){
cin >> n;
int i;
for( i = 0; i < n; ++i )
cin >> a[i];
cin >> y;
retrack(0);
//system("pause");
return 0;
}
被cout和printf的巨大时间差坑了好久…
D:最小重量机器设计问题
- 总时间限制:
- 1000ms
- 内存限制:
- 32768kB
- 描述
某设备需要N种配件(编号1~N), 每种1个. 有M个供应商(编号1~M), 每一个供应商都能提供这N种配件.
然而, 不同供应商提供的同一种配件不仅有不同的价格, 也拥有不用的重量.
现在, 你可以从这M个供应商中任意购买N种配件(每种1个), 但是你只有V元钱.
求使得总重量最小的方案.- 输入
- 第一行有3个正整数, 分别为N,M,V.
接下来的N行, 每一行都有2*M个用空格分开的正整数, 其中:
第i+1行的第2*j-1个数表示第j个供应商提供的第i种零件的价格(单位:元),
第i+1行的第2*j个数表示第j个供应商提供的第i种零件的重量
1<=i<=N, 1<=j<=M
- 输出
- 只有一行
如果没有可行方案, 输出-1
否则, 这一行应该包含用空格分隔的N个整数, 第i个整数表示你选择的第i种零件的供应商.
如果有多个方案, 那么输出第1种零件供应商编号最小的那个, 如果还是有多个, 输出第2种零件供应商编号最小的那个, 类推.
- 样例输入
2 2 10 6 2 4 1 5 1 3 1
- 样例输出
2 1
- 提示
- N和M均不超过8
所有配件的重量和价格都是不超过50的正整数
样例解释: 第一个供应商提供的1号配件价格是6, 重量是2. 2号配件价格是5, 重量是1. 第二个供应商提供的1号配件价格是4, 重量是1. 2号配件价格是3, 重量是1.
最小的重量和显然是2, 可以两种配件都选择第二个供应商, 也可以1号配件选第二个, 2号配件选择第一个供应商
根据题目表述,应该选择后面这个方案
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int N, M, V;
struct ITEM{
int price;
int weight;
}item[10][10];
int ans[10] = {};
int tmp[10] = {};
int answ = 999999;
void reback( int tprice, int tw, int id ){
int i;
if( tprice > V )
return;
if( id > N ){
if( answ > tw ){
answ = tw;
for( i = 1; i <= N; ++i )
ans[i] = tmp[i];
}
return;
}
for( i = 1; i <= M; ++i ){
tmp[id] = i;
reback( (tprice + item[id][i].price), (tw + item[id][i].weight ), id+1);
}
}
int main(){
cin >> N >> M >> V;
int i, j;
for( i = 1; i <= N; ++i ){
for( j = 1; j <= M; ++j )
cin >> item[i][j].price >> item[i][j].weight;
}
reback( 0, 0, 1 );
if( answ == 999999)
printf("-1\n");
else{
for( i = 1; i <= N; ++i )
printf( "%d ", ans[i]);
printf("\n");
}
return 0;
}
这题看起来很像是可以用背包来做。。。不过提示这样写就很明显回溯的顺序了..