题目意思是给你n个数,其中选取一些数使他们的和sum大于给定数M,求满足此条件的Min{M-sum},此题可以装化为01背包问题,刚开始可以把所有的数都加起来这时的sum一定大于M的,但此时的sum-M不一定是最小的,怎么才能得到最小的呢。可以这样想,令B=sum-M,要尽量在这B中减去一些原来加进去数,这样会使sum-M的差逐渐减小,这不就是01背包的模型吗,背包的容量为B,物品的价值与体积相同。尽量使其价值最大,那最后的到的差当然就是最小的。
#include <iostream>
using namespace std;
int N,H;
int cows[25];
int f[1000001];
int inline max(int a, int b){
return a>b?a:b;
}
int main(){
int sum=0, i,j;
cin>>N>>H;
for(i=1; i<=N; ++i){
cin>>cows[i];
sum+=cows[i];
}
int m = sum - H;
for(i=1; i<=N; ++i)
//ZeroOnePack(w[i], c[i])
for(j=m; j>=cows[i]; --j)
f[j]=max(f[j], f[j-cows[i]]+cows[i]);
cout<<m-f[m]<<endl;
return 0;
}
参考:http://hi.baidu.com/zhouxc07/blog/item/898a103c35b886ce9e3d6262.html
posted @
2010-12-08 11:21 小阮 阅读(253) |
评论 (0) |
编辑 收藏
/**//*
ID: lorelei3
TASK: ttwo
LANG: C++
*/
#include <fstream>
using namespace std;
ifstream fin;
ofstream fout;
const int MAX = 10000000;
int dx[] = { -1, 0, 1, 0 };
int dy[] = { 0, 1, 0, -1 };
int cd=0, cx, cy;
int fd=0, fx, fy;
int map[10][10];
int main(){
int i,j;
char ch;
fin.open("ttwo.in");
fout.open("ttwo.out");
for(i=0; i<10; i++)
for(j=0; j<10; j++){
fin>>ch;
if(ch=='*'){
map[i][j]=1;
}else if(ch=='C'){
cx=i, cy=j;
}else if(ch=='F'){
fx=i, fy=j;
}
}
int step=0;
int x,y;
while(step!=MAX){
// for cows
x = cx+dx[cd];
y = cy+dy[cd];
if(map[x][y]==1 || x<0 || x>9 || y<0 || y>9)
cd = (cd+1)%4;
else{
cx = x;
cy = y;
}
// for farmer
x = fx+dx[fd];
y = fy+dy[fd];
if(map[x][y]==1 || x<0 || x>9 || y<0 || y>9)
fd = (fd+1)%4;
else{
fx = x;
fy = y;
}
step++;
//compare
if(cx==fx && cy==fy)
break;
}
if(step == MAX)
fout<<0<<endl;
else
fout<<step<<endl;
return 0;
}
posted @
2010-12-08 11:18 小阮 阅读(218) |
评论 (0) |
编辑 收藏
唉..做得烂洗了..
/**//*
ID: lorelei3
TASK: concom
LANG: C++
*/
#include <fstream>
#include <memory.h>
using namespace std;
const int MAX = 101;
const int NCON = 100;
int N,x;
int a[MAX][MAX];
int c[MAX];
bool f[MAX];
ifstream fin;
ofstream fout;
void dfs(int k){
f[k]=true;
for(int i=1; i<=NCON; ++i){
c[i] += a[k][i];
if(!f[i] && c[i]>50){
dfs(i);
}
}
}
void show(){
for(int i=1; i<=NCON; ++i)
if(i!=x && c[i]>50)
fout<<x<<" "<<i<<endl;
return;
}
int main(){
int i,j,p,k;
fin.open("concom.in");
fout.open("concom.out");
fin>>N;
for(k=0; k<N; k++){
fin>>i>>j>>p;
a[i][j]=p;
}
for(k=1; k<=NCON; ++k){
memset(f, 0, sizeof(f));
memset(c, 0, sizeof(c));
x=k;
dfs(k);
show();
}
return 0;
}
posted @
2010-12-07 21:28 小阮 阅读(490) |
评论 (0) |
编辑 收藏
很标准的01 背包问题
for(i=1; i<=N; ++i)
//ZeroOnePack( w[i], c[i])
for(j = V; j>= weight; j--)
f[j] = max( f[j], f[j-cost[i]]+w[i])
#include <iostream>
using namespace std;
int w[3500], d[3500];
int f[13000];
int N,M;
inline int max(int a, int b){
return a>b? a: b;
}
int main(){
int i,j;
cin>>N>>M;
for(i=1; i<=N; ++i)
cin>>w[i]>>d[i];
for(i=1; i<=N; ++i)
// ZeroOnePack(w[i], d[i])
for(j=M; j>=w[i]; j--)
f[j] = max(f[j], f[j-w[i]]+d[i]);
cout<<f[M]<<endl;
return 0;
}
posted @
2010-12-07 16:05 小阮 阅读(161) |
评论 (0) |
编辑 收藏
01 背包问题.
f[i][j] 表示将前i个物品放入力矩为j的可行方案
f[i][j] = sum{ f[i-1][j-w[i][k] }
#include <iostream>
using namespace std;
const int mid = 6000;
int w[25],v[25];
int f[25][mid+mid];
int C,G;
int main(){
int i,j,k;
cin>>C>>G;
for(i=1; i<=C; ++i) cin>>v[i];
for(i=1; i<=G; ++i) cin>>w[i];
for(i=1; i<=C; ++i)
f[1][mid+v[i]*w[1]] = 1;
for(i=2; i<=G; ++i)
for(j=1; j<=C; ++j)
for(k=0; k<=2*mid; ++k)
if(f[i-1][k]>0)
f[i][k+w[i]*v[j]] += f[i-1][k];
cout<<f[G][mid]<<endl;
return 0;
}
posted @
2010-12-07 12:18 小阮 阅读(114) |
评论 (0) |
编辑 收藏
完全背包问题.
只是将完全背包问题的max 改为 sum
/**//*
ID: lorelei3
TASK: money
LANG: C++
*/
#include <fstream>
using namespace std;
const int V = 30;
const int MAX = 10005;
long long f[MAX];
int c[V];
int N;
int main(){
int i,j,n;
ifstream fin;
ofstream fout;
fin.open("money.in");
fout.open("money.out");
fin>>n>>N;
for(i=1; i<=n; ++i)
fin>>c[i];
f[0]=1;
for(i=1; i<=n; ++i)
for(j=c[i]; j<=N; ++j)
f[j] = f[j] + f[j-c[i]];
fout<<f[N]<<endl;
return 0;
}
posted @
2010-12-06 13:14 小阮 阅读(116) |
评论 (0) |
编辑 收藏
/**//*
ID: lorelei3
TASK: lamps
LANG: C++
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
const int C = 4;
const int MAXN = 6;
const int MASK = (1<<MAXN)-1;
int loc[1<<MAXN];
int n,c,t;
int open_mask, tot_mask;
int op[4] = { MASK,
MASK & 0xAA,
MASK & 0x55,
MASK & ( (1<<(MAXN-1)) | (1<<(MAXN-4)) )
};
FILE *fin, *fout;
void wirte(int lights){
int i;
char s[105];
for(i=0; i<n; ++i)
s[i] = ( lights & (1<<(MAXN-1-(i%MAXN))) ) ? '1': '0';
s[i]='\0';
fprintf(fout, "%s\n", s);
}
void dfs(int lights, int i, int n){
if(n==c){
if( (lights&tot_mask)==open_mask){
loc[lights]=1;
return;
}
}else
for( ; i<4; ++i)
dfs( lights^op[i], i+1, n+1);
}
int main(){
int i;
fin = fopen("lamps.in", "r");
fout = fopen("lamps.out", "w");
assert(fin!=NULL && fout!=NULL);
fscanf(fin, "%d %d", &n, &c);
for(;;){
fscanf(fin, "%d", &t);
if(t==-1) break;
t = MAXN-1-(t-1)%MAXN;
open_mask |= (1<<t);
tot_mask |= (1<<t);
}
for(;;){
fscanf(fin, "%d", &t);
if(t==-1) break;
t = MAXN-1-(t-1)%MAXN;
tot_mask |= (1<<t);
}
if(c>4){
if(c%2==0)
c=4;
else
c=3;
}
for(i=0; i<=c; i+=2)
dfs(MASK, 0, i);
bool flag=false;
for(i=0; i< (1<<MAXN); ++i)
if(loc[i]){
flag = true;
wirte(i);
}
if(!flag)
fprintf(fout, "IMPOSSIBLE\n");
return 0;
}
posted @
2010-11-21 00:49 小阮 阅读(142) |
评论 (0) |
编辑 收藏
/**//*
ID: lorelei3
TASK: runround
LANG: C++
*/
#include <iostream>
#include <string.h>
#include <fstream>
using namespace std;
const int N = 15;
bool num_check(int n){
char num[N];
bool used[10];
int i, len;
memset(used, 0, sizeof(used));
sprintf(num, "%d", n);
len=strlen(num);
for(i=0; i<len; ++i)
if(used[num[i]-'0'] == true || num[i]=='0')
return false;
else
used[num[i]-'0'] = true;
return true;
}
bool round_check(int n){
char num[N];
bool f[N];
int steps, i, len;
memset(f, 0, sizeof(f));
sprintf(num, "%d", n);
len=strlen(num);
steps=0, i=0;
while(steps<len){
if(f[i]==true)
return false;
else
f[i] = true;
i = (i+num[i]-'0') % len;
steps++;
}
if(i==0)
return true;
else
return false;
}
int main(){
int n,num;
ifstream in("runround.in");
ofstream out("runround.out");
in>>n;
for(num=n+1; ;num++)
if(num_check(num) && round_check(num))
break;
out<<num<<endl;
return 0;
}
posted @
2010-11-21 00:49 小阮 阅读(181) |
评论 (0) |
编辑 收藏
/**//*
ID: lorelei3
TASK: subset
LANG: C++
*/
#include<stdio.h>
const int N = 40;
const int MAX = (1+N)*N/4;
long long ans[N][MAX];
int main(){
int n, tot, sum;
freopen("subset.in", "r", stdin);
freopen("subset.out", "w", stdout);
scanf("%d", &n);
tot = (1+n)*n/2;
if(tot&0x01){
printf("0\n");
return 0;
}
sum = tot/2;
ans[1][0] = 1; ans[1][1] = 1;
for(int i=2; i<=n; ++i)
for(int j=0; j<=sum; ++j)
if(j-i>=0)
ans[i][j]=ans[i-1][j]+ans[i-1][j-i];
else
ans[i][j]=ans[i-1][j];
printf("%lld\n", ans[n][sum]/2);
return 0;
}
posted @
2010-11-21 00:48 小阮 阅读(175) |
评论 (0) |
编辑 收藏
/**//*
ID: lorelei3
TASK: preface
LANG: C
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
static char *encode[] = {
"", "I", "II", "III", "IV",
"V", "VI", "VII", "VIII", "IX",
};
char*
romandigit(int d, char *ivx)
{
char *s, *p;
static char str[10];
for(s=encode[d%10], p=str; *s; s++, p++) {
switch(*s){
case 'I':
*p = ivx[0];
break;
case 'V':
*p = ivx[1];
break;
case 'X':
*p = ivx[2];
break;
}
}
*p = '\0';
return str;
}
char*
roman(int n)
{
static char buf[20];
strcpy(buf, "");
strcat(buf, romandigit(n/1000, "M"));
strcat(buf, romandigit(n/100, "CDM"));
strcat(buf, romandigit(n/10, "XLC"));
strcat(buf, romandigit(n, "IVX"));
return buf;
}
int
main(void)
{
FILE *fin, *fout;
int i, n;
char *s;
int count[256];
fin = fopen("preface.in", "r");
fout = fopen("preface.out", "w");
assert(fin != NULL && fout != NULL);
fscanf(fin, "%d", &n);
for(s="IVXLCDM"; *s; s++)
count[*s] = 0;
for(i=1; i<=n; i++)
for(s=roman(i); *s; s++)
count[*s]++;
for(s="IVXLCDM"; *s; s++)
if(count[*s])
fprintf(fout, "%c %d\n", *s, count[*s]);
return 0;
}
posted @
2010-11-21 00:47 小阮 阅读(152) |
评论 (0) |
编辑 收藏